JOIN 和 CASE 复制查询结果

JOIN and CASE duplicating Query results

我正在使用 Teradata 中的两个表,我正在尝试按商店编号、总销售天数和每个商店编号中的总天数查询每个活动项目。我当前的查询设置是按 SKU 提供两行数据,而不是提供显示相应信息的一行。

Table 1: 显示class号码、class姓名、状态和存储数据。

Store   Item    Class Number    Class Name         Status
100     Apple      10            Red Fruit         Active
200     Apple      10            Red Fruit         Active
100     Banana     12            Yellow Fruit      Active
200     Banana     12            Yellow Fruit      Active
100     Pear       14            Green Fruit       Active
200     Pear       14            Green Fruit       Active
100     Beans      20            Green Vegetable   Discontinued
200     Beans      20            Green Vegetable   Active

Table 2:按商店和商品显示总销售天数

Store   Item    Total Days to sell
100     Apple         4
200     Apple         1
100     Banana        2
200     Banana        4
100     Pear          3
200     Pear          6
100     Beans        NULL
200     Beans         4

Table 3: 当前查询结果

Item  Class Number   Class Name  Total Days to sell  Store 100   Store 200
Apple     10         Red Fruit           5               4         NULL
Apple     10         Red Fruit           5              NULL        1
Banana    12         Yellow Fruit        6               2         NULL
Banana    12         Yellow Fruit        6              NULL        4
Pear      14         Green Fruit         9               3         NULL
Pear      14         Green Fruit         9              NULL        6
Beans     20         Green Vegetable     4              NULL        4

以下是我如何查找要组织的数据:

Item    Class Number    Class Name  Total Days to sell  Store 100   Store 200
Apple     10             Red Fruit          5              4           1
Banana    12             Yellow Fruit       6              2           4
Pear      14             Green Fruit        9              3           6
Beans     20             Green Vegetable    4             NULL         4

当前查询:

SELECT DISTINCT     
    A.ITEM, 
    A.CLASS_NUMBER, 
    A.CLASS_NAME,   
    SUM(B.TOTAL_DAYS_TO_SELL),  
    CASE    
        WHEN B.STORE=100 THEN B.TOTAL_DAYS_TO_SELL
        ELSE NULL
        END AS STORE 100,
    CASE    
        WHEN B.STORE=200 THEN B.TOTAL_DAYS_TO_SELL
        ELSE NULL
        END AS STORE 200
FROM TABLE 1 A      
RIGHT JOIN TABLE 2 B        
ON B.ITEM=A.ITEM        
WHERE A.STATUS='ACTIVE'     
GROUP BY        
    A.ITEM, 
    A.CLASS_NUMBER, 
    A.CLASS_NAME,   
    STORE 100,  
    STORE 200   
ORDER BY        
    A.CLASS_NUMBER ASC; 

如果您对这些信息有任何疑问,请告诉我

谢谢!

首先,不需要 DISTINCT,因为您使用的是 GROUP BY

对于您想要的结果,您需要对正在使用的 CASE 表达式使用聚合函数。根据您显示的数据,您可以使用 MINMAXSUM(甚至 AVG):

SELECT DISTINCT     
    A.ITEM, 
    A.CLASS_NUMBER, 
    A.CLASS_NAME,   
    SUM(B.TOTAL_DAYS_TO_SELL),  
    MIN(CASE    
            WHEN B.STORE=100 THEN B.TOTAL_DAYS_TO_SELL
            ELSE NULL
         END) AS STORE 100,
    MIN(CASE    
            WHEN B.STORE=200 THEN B.TOTAL_DAYS_TO_SELL
            ELSE NULL
        END) AS STORE 200
FROM TABLE 1 A      
RIGHT JOIN TABLE 2 B        
ON B.ITEM=A.ITEM        
WHERE A.STATUS='ACTIVE'     
GROUP BY        
    A.ITEM, 
    A.CLASS_NUMBER, 
    A.CLASS_NAME
ORDER BY        
    A.CLASS_NUMBER ASC; 

我会这样写:

SELECT A.ITEM, A.CLASS_NUMBER, A.CLASS_NAME, SUM(B.TOTAL_DAYS_TO_SELL),  
       SUM(CASE WHEN B.STORE = 100 THEN B.TOTAL_DAYS_TO_SELL END) as STORE_100,
       SUM(CASE WHEN B.STORE = 200 THEN B.TOTAL_DAYS_TO_SELL END) as STORE_200
FROM TABLE1 A JOIN     
     TABLE2 B        
     ON B.ITEM = A.ITEM        
WHERE A.STATUS = 'ACTIVE'     
GROUP BY A.ITEM, A.CLASS_NUMBER, A.CLASS_NAME
ORDER BY A.CLASS_NUMBER ASC;

这基本上是 Lamak 的回答,但有更多社论:

  • 除非您真的知道自己在做什么,否则不要使用 SELECT DISTINCT。它几乎不适合 GROUP BY.
  • 您有三列未聚合;这些应该是 GROUP BY.
  • 中的那些
  • 您的 RIGHT OUTER JOIN 正被 WHERE 子句变成 INNER JOIN。只需使用 INNER JOIN。此外,您正在按 A 中的列进行聚合。您真的想要 NULL 的聚合列吗?
  • CASE 不需要 ELSE 子句,因为默认值为 NULL
  • 此版本选择 SUM() 进行聚合。对于一个数值,SUM()MIN()MAX() 都是 return 相同的东西。但是,我认为如果您想删除一些聚合键,SUM() 更安全。