日期:2014-05-17  浏览次数:21363 次

SQL关于GROUP BY字段为空的处理.
现在我有多个表关联,其中表中的字段里新增加了一列invoice_no但是,此列为空值,由用户后期修改的,但是在我GROUP BY后全部都分到一个组里了。
我想将内容为空的不分到一个组里,全部都显示出来要怎么做?
但是,如果invoice_no不包含在GROUP BY中,就会报:选择列表中的列 'AMS_EQUIP_BUY.invoice_no' 无效,因为该列没有包含在聚合函数或 GROUP BY 子句中。

求修改方法。

SELECT
eb.invoice_no,
e.equip_name,
e.unit,
isnull(dtl1.type_name, '') + ' ' + isnull(dtl.type_name, '') AS type_name,
eb.funds_source,
eb.buy_date,
eb.price,
SUM (eb.equip_num) AS num,
(eb.price * SUM(eb.equip_num)) AS total_price
FROM
AMS_EQUIP e
LEFT JOIN AMS_EQUIP_BUY eb ON e.buy_id = eb.buy_id
LEFT JOIN ams_type_record_relation r ON e.equip_id = r.record_id
AND r.use_name = 'equipAccount'
LEFT JOIN ams_type_detail dtl ON r.type_id = dtl.type_id
LEFT JOIN ams_type_detail dtl1 ON dtl.parent_id = dtl1.type_id
LEFT JOIN AMS_EQUIP_DEPT ed ON ed.equip_id = e.equip_id
${request.whereCondition}
GROUP BY
eb.invoice_no,
e.equip_name,
e.unit,
eb.funds_source,
eb.buy_date,
eb.price,
dtl1.type_name,
dtl.type_name

------解决方案--------------------
引用:
引用:联机丛书:如果组合列包含 Null 值,则所有的 Null 值都将被视为相等,并会置入一个组中。

下面是我自己的话:当你那个列有值之后,自然就不在一组了,
我现在的意图,就是不想让那一列分组,但是聚集索引下,必须得指定invoice_no这一列,这怎么办?
这跟聚集索引什么关系啊?T-SQL的执行顺序是先from然后....然后group by,再select的,而你那个是因为groupby没出现那列,所以SELECT也就不行了,,你那列需要进行聚合运算吗?
------解决方案--------------------
换一个思路,你可以增加一个临时列,把null行的分开。
------解决方案--------------------
引用:
引用:
引用:引用:联机丛书:如果组合列包含 Null 值,则所有的 Null 值都将被视为相等,并会置入一个组中。

下面是我自己的话:当你那个列有值之后,自然就不在一组了,
我现在的意图,就是不想让那一列分组,但是聚集索引下,必须得指定invoice_no这一列,这怎么办?这跟……
null对于SQLServer的group by来说就是同一个值,分不开的。
------解决方案--------------------
可以,但是会有一些难度,现在假设一下,一个表有2列,一列就是你那个null的列,一列是A,有数据,那么group by的时候,如果不加入group by a,那么全部分到一组,当你再加一列B的话,问题就来了,除非你这个列B的每一行的值都是唯一的,否则始终会有几行或者很多行,会因为B的值有重复而导致多行NULL值依旧分在同一组
------解决方案--------------------
是这个意思吧!?
with tb(a,b) as
(
select null, 1 union all
select null, 2 union all
select    3, 3 union all
select    3, 4
)
select a, sum(b) from tb group by isnull(a,checksum(newid())), a
/*
a           
----------- -----------
NULL        1
NULL        2
3           7

(3 行受影响)

*/

如果是,想办法把newid转换成invoice_no的数据类型,这里假设int,所以用checksum。