繁体   English   中英

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

[英]SQL using CASE in SELECT with GROUP BY. Need CASE-value but get row-value

所以基本上有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,因为我已经在解释顶部。

在这里,女士们,先生们是问题的解决方案:

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:谢谢!

@其他: ...

实际上有一个通配符相等测试。 我不确定你为什么要按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

对于无法比较的数据类型,这将失败

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

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

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

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

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

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

select * from A
 INTERSECT DISTINCT
select * from B

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM