SQL (Teradata):删除由 GroupBy / CASE 语句引起的 NULL
SQL (Teradata): Removing NULLs caused by GroupBy / CASE Statement
我的结果中出现 NULL 时遇到问题。这是因为我如何使用我的 Group By & CASE 语句 "ItemDamagedStatus"。一种解决方案可能是分解那些 CASE 语句项并对相同的 table 执行 JOIN。但是,当我这样做时,一些数据被丢弃了。
下面的查询实际上给了我正确的数字。我只是希望它基于以下内容汇总到一行:Product/Market/Group1.
想法?有问题吗?
SELECT t1.Product
, t1.Market
, t1.Group1
, COUNT(DISTINCT t1.ItemID ||'-'||t1.Date1) AS StoredMth
, CASE WHEN t1.ItemDamagedStatus = 'C' THEN COUNT(DISTINCT t1.ItemID ||'-'|| t1.Date1) END AS CompleteDmgMth
, CASE WHEN t1.ItemDamagedStatus = 'P' THEN COUNT(DISTINCT t1.ItemID ||'-'|| t1.Date1) END AS PartialDmgMth
, CASE WHEN t1.ItemDamagedStatus = 'N' THEN COUNT(DISTINCT t1.ItemID ||'-'|| t1.Date1) END AS NotDmgMth
, CASE WHEN t1.ItemRepairStatus = 'Y' THEN COUNT(DISTINCT t1.ItemID ||'-'|| t1.Date1) END AS RepairMth
FROM MainDatabase.Items t1
WHERE t1.Date1 BETWEEN '2017-01-01' AND '2017-12-31'
GROUP BY t1.Product
, t1.Market
, t1.Group1
, t1.ItemDamagedStatus
, t1.ItemRepairStatus
我得到的结果:
Product Market Group1 StoredMth CompleteDmgMth PartialDmgMth NotDmgMth RepairMth
Car North Y 950 50 NULL NULL 75
Car North Y NULL NULL 100 NULL NULL
Car North Y NULL NULL NULL 800 NULL
Car North N 165 NULL 75 NULL 10
Car North N NULL NULL NULL 90 NULL
Car South Y 1400 500 NULL NULL 800
Car South Y NULL NULL NULL 900 NULL
我想要的结果:
Product Market Group1 StoredMth CompleteDmgMth PartialDmgMth NotDmgMth RepairMth
Car North Y 950 50 100 800 75
Car North N 165 NULL 75 90 10
Car South Y 1400 500 NULL 900 800
(只是一个跟进,以防万一这会让任何人失望或他们试图合并一些值......是的:CompleteDmgMth + PartialDmgMth + NotDmgMth = StoredMth,但它在我们的数据中并不是一直都非常准确,所以我们使用两种不同的方法。)
我第一次在这里发帖,如果有些东西看起来很奇怪或装裱不正确,我深表歉意。
您可以使用 MAX 仅捕获非空值,而不是对这些字段进行分组:
SELECT derived_table.Product,
derived_table.Market
, derived_table.Group1
, MAX(derived_table.StoredMth) as StoredMth
, MAX(derived_table.CompleteDmgMth) as CompleteDmgMth
, MAX(derived_table.PartialDmgMth) as PartialDmgMth
, MAX(derived_table.NotDmgMth) as NotDmgMth
, MAX(derived_table.RepairMth) as RepairMth
FROM (
SELECT t1.Product
, t1.Market
, t1.Group1
, COUNT(DISTINCT t1.ItemID ||'-'||t1.Date1) AS StoredMth
, CASE WHEN t1.ItemDamagedStatus = 'C' THEN COUNT(DISTINCT t1.ItemID ||'-'|| t1.Date1) END AS CompleteDmgMth
, CASE WHEN t1.ItemDamagedStatus = 'P' THEN COUNT(DISTINCT t1.ItemID ||'-'|| t1.Date1) END AS PartialDmgMth
, CASE WHEN t1.ItemDamagedStatus = 'N' THEN COUNT(DISTINCT t1.ItemID ||'-'|| t1.Date1) END AS NotDmgMth
, CASE WHEN t1.ItemRepairStatus = 'Y' THEN COUNT(DISTINCT t1.ItemID ||'-'|| t1.Date1) END AS RepairMth
FROM MainDatabase.Items t1
WHERE t1.Date1 BETWEEN '2017-01-01' AND '2017-12-31'
GROUP BY t1.Product
, t1.Market
, t1.Group1
, t1.ItemDamagedStatus
, t1.ItemRepairStatus) as derived_table
GROUP BY derived_table.Product,
derived_table.Market
, derived_table.Group1;
使用聚合,但不是对所有列。您可以将 CASE
表达式嵌套在 COUNT(DISTINCT)
:
中
SELECT t1.Product, t1.Market, t1.Group1,
COUNT(DISTINCT t1.ItemID || '-' || t1.Date1) AS StoredMth
COUNT(DISTINCT CASE WHEN t1.ItemDamagedStatus = 'C' THEN t1.ItemID || '' || t1.Date1) END) AS CompleteDmgMth
COUNT(DISTINCT CASE WHEN t1.ItemDamagedStatus = 'P' THEN t1.ItemID || '' || t1.Date1 END) AS PartialDmgMth
COUNT(DISTINCT CASE WHEN t1.ItemDamagedStatus = 'N' THEN t1.ItemID || '-' || t1.Date1 END) AS NotDmgMth
COUNT(DISTINCT CASE WHEN t1.ItemRepairStatus = 'Y' THEN t1.ItemID || '-' || t1.Date1 END) AS RepairMth
FROM MainDatabase.Items t1
WHERE t1.Date1 BETWEEN '2017-01-01' AND '2017-12-31'
GROUP BY t1.Product, t1.Market, t1.Group1;
我的结果中出现 NULL 时遇到问题。这是因为我如何使用我的 Group By & CASE 语句 "ItemDamagedStatus"。一种解决方案可能是分解那些 CASE 语句项并对相同的 table 执行 JOIN。但是,当我这样做时,一些数据被丢弃了。
下面的查询实际上给了我正确的数字。我只是希望它基于以下内容汇总到一行:Product/Market/Group1.
想法?有问题吗?
SELECT t1.Product
, t1.Market
, t1.Group1
, COUNT(DISTINCT t1.ItemID ||'-'||t1.Date1) AS StoredMth
, CASE WHEN t1.ItemDamagedStatus = 'C' THEN COUNT(DISTINCT t1.ItemID ||'-'|| t1.Date1) END AS CompleteDmgMth
, CASE WHEN t1.ItemDamagedStatus = 'P' THEN COUNT(DISTINCT t1.ItemID ||'-'|| t1.Date1) END AS PartialDmgMth
, CASE WHEN t1.ItemDamagedStatus = 'N' THEN COUNT(DISTINCT t1.ItemID ||'-'|| t1.Date1) END AS NotDmgMth
, CASE WHEN t1.ItemRepairStatus = 'Y' THEN COUNT(DISTINCT t1.ItemID ||'-'|| t1.Date1) END AS RepairMth
FROM MainDatabase.Items t1
WHERE t1.Date1 BETWEEN '2017-01-01' AND '2017-12-31'
GROUP BY t1.Product
, t1.Market
, t1.Group1
, t1.ItemDamagedStatus
, t1.ItemRepairStatus
我得到的结果:
Product Market Group1 StoredMth CompleteDmgMth PartialDmgMth NotDmgMth RepairMth
Car North Y 950 50 NULL NULL 75
Car North Y NULL NULL 100 NULL NULL
Car North Y NULL NULL NULL 800 NULL
Car North N 165 NULL 75 NULL 10
Car North N NULL NULL NULL 90 NULL
Car South Y 1400 500 NULL NULL 800
Car South Y NULL NULL NULL 900 NULL
我想要的结果:
Product Market Group1 StoredMth CompleteDmgMth PartialDmgMth NotDmgMth RepairMth
Car North Y 950 50 100 800 75
Car North N 165 NULL 75 90 10
Car South Y 1400 500 NULL 900 800
(只是一个跟进,以防万一这会让任何人失望或他们试图合并一些值......是的:CompleteDmgMth + PartialDmgMth + NotDmgMth = StoredMth,但它在我们的数据中并不是一直都非常准确,所以我们使用两种不同的方法。)
我第一次在这里发帖,如果有些东西看起来很奇怪或装裱不正确,我深表歉意。
您可以使用 MAX 仅捕获非空值,而不是对这些字段进行分组:
SELECT derived_table.Product,
derived_table.Market
, derived_table.Group1
, MAX(derived_table.StoredMth) as StoredMth
, MAX(derived_table.CompleteDmgMth) as CompleteDmgMth
, MAX(derived_table.PartialDmgMth) as PartialDmgMth
, MAX(derived_table.NotDmgMth) as NotDmgMth
, MAX(derived_table.RepairMth) as RepairMth
FROM (
SELECT t1.Product
, t1.Market
, t1.Group1
, COUNT(DISTINCT t1.ItemID ||'-'||t1.Date1) AS StoredMth
, CASE WHEN t1.ItemDamagedStatus = 'C' THEN COUNT(DISTINCT t1.ItemID ||'-'|| t1.Date1) END AS CompleteDmgMth
, CASE WHEN t1.ItemDamagedStatus = 'P' THEN COUNT(DISTINCT t1.ItemID ||'-'|| t1.Date1) END AS PartialDmgMth
, CASE WHEN t1.ItemDamagedStatus = 'N' THEN COUNT(DISTINCT t1.ItemID ||'-'|| t1.Date1) END AS NotDmgMth
, CASE WHEN t1.ItemRepairStatus = 'Y' THEN COUNT(DISTINCT t1.ItemID ||'-'|| t1.Date1) END AS RepairMth
FROM MainDatabase.Items t1
WHERE t1.Date1 BETWEEN '2017-01-01' AND '2017-12-31'
GROUP BY t1.Product
, t1.Market
, t1.Group1
, t1.ItemDamagedStatus
, t1.ItemRepairStatus) as derived_table
GROUP BY derived_table.Product,
derived_table.Market
, derived_table.Group1;
使用聚合,但不是对所有列。您可以将 CASE
表达式嵌套在 COUNT(DISTINCT)
:
SELECT t1.Product, t1.Market, t1.Group1,
COUNT(DISTINCT t1.ItemID || '-' || t1.Date1) AS StoredMth
COUNT(DISTINCT CASE WHEN t1.ItemDamagedStatus = 'C' THEN t1.ItemID || '' || t1.Date1) END) AS CompleteDmgMth
COUNT(DISTINCT CASE WHEN t1.ItemDamagedStatus = 'P' THEN t1.ItemID || '' || t1.Date1 END) AS PartialDmgMth
COUNT(DISTINCT CASE WHEN t1.ItemDamagedStatus = 'N' THEN t1.ItemID || '-' || t1.Date1 END) AS NotDmgMth
COUNT(DISTINCT CASE WHEN t1.ItemRepairStatus = 'Y' THEN t1.ItemID || '-' || t1.Date1 END) AS RepairMth
FROM MainDatabase.Items t1
WHERE t1.Date1 BETWEEN '2017-01-01' AND '2017-12-31'
GROUP BY t1.Product, t1.Market, t1.Group1;