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
表达式使用聚合函数。根据您显示的数据,您可以使用 MIN
、MAX
或 SUM
(甚至 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()
更安全。
我正在使用 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
表达式使用聚合函数。根据您显示的数据,您可以使用 MIN
、MAX
或 SUM
(甚至 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()
更安全。