SQL中使用带有GROUP BY的CASE的SQL。需要CASE值但获取行值

时间:2013-07-31 14:33:30

标签: sql db2 case where

基本上有1个问题和1个问题:

1。问题 - 当我在一个表中有100列(并且没有设置键或uindex)并且我想加入或者自己选择该表时,我是否真的必须写出每个列的名称?

2。问题 - 下面的例子显示了1.问题和我的实际SQL语句问题

示例:

A.FIELD1,
(SELECT CASE WHEN B.FIELD2 = 1 THEN B.FIELD3 ELSE null FROM TABLE B WHERE A.* = B.*) AS CASEFIELD1
(SELECT CASE WHEN B.FIELD2 = 2 THEN B.FIELD4 ELSE null FROM TABLE B WHERE A.* = B.*) AS CASEFIELD2
FROM TABLE A
GROUP BY A.FIELD1

故事是:如果我没有将CASE放入其自己的select语句中,那么我必须将实际的rowname放入GROUP BY中,而GROUP BY不会将CASE中的NULL值分组,而是实际的行中的值。因此,我必须加入或选择所有列,因为没有键,没有uindex,或者以某种方式找到另一种解决方案。

DBServer是DB2。

所以现在只用单词而不是SQL来描述它: 我有“订购商品”,可以分为“ZD”和“EK”(1 = ZD,2 = EK),可以按“经销商”分组。即使“订单商品”可以具有两个不同的“部分”(ZD,EK)中的一个,但“ZD”和“EK”的字段/行始终都被填充。我需要分组来考虑“离开”,并且只有当指定的“部门”(ZD或EK)发生变化时,我才想要创建一个新的组。

SELECT
(CASE WHEN TABLE.DEPARTEMENT = 1 THEN TABLE.ZD ELSE null END) AS ZD,
(CASE WHEN TABLE.DEPARTEMENT = 2 THEN TABLE.EK ELSE null END) AS EK,
TABLE.DISTRIBUTOR,
sum(TABLE.SOMETHING) AS SOMETHING,
FROM TABLE
GROUP BY
ZD
EK
TABLE.DISTRIBUTOR
TABLE.DEPARTEMENT

这在GROUP BY中的SELECT和ZD,EK中有效。唯一的问题是,即使EK不是指定的DEPARTEMENT,它仍会打开一个新的组,如果它改变了,因为他使用的是真正的EK值,而不是来自CASE的NULL,因为我已经在解释顶部。

5 个答案:

答案 0 :(得分:7)

女士们,先生们可以解决这个问题:

SELECT
(CASE WHEN TABLE.DEPARTEMENT = 1 THEN TABLE.ZD ELSE null END) AS ZD,
(CASE WHEN TABLE.DEPARTEMENT = 2 THEN TABLE.EK ELSE null END) AS EK,
TABLE.DISTRIBUTOR,
sum(TABLE.SOMETHING) AS SOMETHING,
FROM TABLE
GROUP BY
(CASE WHEN TABLE.DEPARTEMENT = 1 THEN TABLE.ZD ELSE null END),
(CASE WHEN TABLE.DEPARTEMENT = 2 THEN TABLE.EK ELSE null END),
TABLE.DISTRIBUTOR,
TABLE.DEPARTEMENT

@ t-clausen.dk:谢谢!

@others:...

答案 1 :(得分:2)

实际上有一个通配符相等测试。 我不确定你为什么要按field1分组,这在你的例子中似乎是不可能的。我试着把它放到你的问题中:

SELECT FIELD1,
CASE WHEN FIELD2 = 1 THEN FIELD3 END AS CASEFIELD1,
CASE WHEN FIELD2 = 2 THEN FIELD4 END AS CASEFIELD2
FROM 
(
 SELECT * FROM A
 INTERSECT
 SELECT * FROM B
) C
UNION -- results in a distinct
SELECT
A.FIELD1,
null,
null
FROM 
(
 SELECT * FROM A
 EXCEPT
 SELECT * FROM B
) C

对于无法比较的数据类型

,这将失败

答案 2 :(得分:1)

不,没有通配符相等测试。您必须列出要单独测试的每个字段。如果您不想测试每个字段,可以使用诸如连接所有字段之类的黑客,例如。

WHERE (a.foo + a.bar + a.baz) = (b.foo + b.bar + b.az)

但不管怎样,你列出了所有字段。

答案 3 :(得分:1)

我可能倾向于解决这样的问题

WITH q as
(SELECT
       Department
     , (CASE WHEN DEPARTEMENT = 1 THEN ZD
             WHEN DEPARTEMENT = 2 THEN EK
                                  ELSE null 
        END) AS GRP
     , DISTRIBUTOR
     , SOMETHING 
   FROM mytable
)
SELECT 
       Department
     , Grp
     , Distributor

     , sum(SOMETHING) AS SumTHING
  FROM q
GROUP BY
       DEPARTEMENT 
     , GRP
     , DISTRIBUTOR

答案 4 :(得分:0)

如果您需要查找TableA中与TableB匹配的所有行,那么INTERSECT或INTERSECT DISTINCT如何?

select * from A
 INTERSECT DISTINCT
select * from B

但是,如果您只想要A中的行,其中整行与B中的行中的值匹配,那么为什么您的示例代码从A获取某些值,而从B中获取其他值?如果行匹配所有列,那么这似乎毫无意义。 (也许你的问题可以更充分地解释一下?)