9

所以基本上有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 语句中,那么我必须将实际的行名放入 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,正如我已经在上面解释的那样。

4

5 回答 5

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

@其他: ...

于 2013-08-02T09:27:45.300 回答
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

对于不可比较的数据类型,这将失败

于 2013-07-31T15:57:11.137 回答
1

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

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

但无论哪种方式,您都列出了所有字段。

于 2013-07-31T14:40:08.163 回答
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
于 2013-08-02T11:43:12.947 回答
0

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

select * from A
 INTERSECT DISTINCT
select * from B

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

于 2013-07-31T16:32:29.747 回答