在 SQL 连接操作中,如何从左侧连接获取行,并且仅从右侧获取两列的聚合 table
In an SQL join operation, how to get the rows from the left join and only the aggregate of two columns from the right table
我正在尝试对 tpos 中的数量求和 table 并计算 tpos 中每个项目的不同商店数量。
对于 inv_dtl 中的每一行,tpos table 中可能有多行。我想把一个脚本放在一起,给我 inv_dtl table 中的所有行并添加两个聚合列 sum(tpos.quantiy), count(distinct, tpos.store_number ) 匹配连接条件。
这是我目前所知道的。聚合正在工作,但我的输出包含在 tpos 中匹配的数字或行。
例如 inv_dtl 中的 1 行在 tpos 中可能有 100 行。我的输出应包含 1 行加上两个聚合列,但我当前的脚本生成 100 行。
WITH FT1 As
(
SELECT * FROM inv_dtl WHERE inv_no IN (16084, 23456, 14789)
),
FT2 As
(
SELECT
FT1.*,
SUM(tpos.quantity) OVER (partition by tpos.item_id) As pos_qty,
DENSE_RANK() OVER (partition by tpos.store_number ORDER BY tpos.item_id ASC) +
DENSE_RANK() OVER (partition by tpos.store_number ORDER BY tpos.item_id DESC)
As unique_store_cnt
FROM FT1
LEFT JOIN tpos
ON tpos.item_id = FT1.ITEM_ID
And tpos.movement_date Between FT1.SDATE And FT1.EDATE
And tpos.store_number != 'CMPNY'
)
SELECT * FROM FT2 ORDER BY ITEM_ID
只需使用常规的 GROUP BY 即可减少行数。但是因为我不知道你想要第一个提到的列是什么 table 所以我刚刚发明了 4 作为例子。
WITH
FT1 AS (
SELECT
col1, col2, col3, col4
FROM inv_dtl
WHERE inv_no IN (16084, 23456, 14789)
),
FT3 AS (
SELECT
FT1.col1, FT1.col2, FT1.col3, FT1.col4
, SUM(tpos.quantity) OVER (PARTITION BY tpos.item_id) AS pos_qty
, ROW_NUMBER() OVER (PARTITION BY col1, col2, col3, col4 ASC) +
AS unique_store_cnt
FROM FT1
LEFT JOIN tpos ON tpos.item_id = FT1.ITEM_ID
AND tpos.movement_date BETWEEN FT1.SDATE AND FT1.EDATE
AND tpos.store_number != 'CMPNY'
GROUP BY
FT1.col1, FT1.col2, FT1.col3, FT1.col4
)
SELECT
*
FROM FT3
ORDER BY col1, col2, col3, col4
请注意,如果数据是 "equal rank",RANK()
和 DENSE_RANK()
可以重复数字。要保证每行的唯一整数,请改用 ROW_NUMBER()
。
我正在尝试对 tpos 中的数量求和 table 并计算 tpos 中每个项目的不同商店数量。
对于 inv_dtl 中的每一行,tpos table 中可能有多行。我想把一个脚本放在一起,给我 inv_dtl table 中的所有行并添加两个聚合列 sum(tpos.quantiy), count(distinct, tpos.store_number ) 匹配连接条件。
这是我目前所知道的。聚合正在工作,但我的输出包含在 tpos 中匹配的数字或行。
例如 inv_dtl 中的 1 行在 tpos 中可能有 100 行。我的输出应包含 1 行加上两个聚合列,但我当前的脚本生成 100 行。
WITH FT1 As
(
SELECT * FROM inv_dtl WHERE inv_no IN (16084, 23456, 14789)
),
FT2 As
(
SELECT
FT1.*,
SUM(tpos.quantity) OVER (partition by tpos.item_id) As pos_qty,
DENSE_RANK() OVER (partition by tpos.store_number ORDER BY tpos.item_id ASC) +
DENSE_RANK() OVER (partition by tpos.store_number ORDER BY tpos.item_id DESC)
As unique_store_cnt
FROM FT1
LEFT JOIN tpos
ON tpos.item_id = FT1.ITEM_ID
And tpos.movement_date Between FT1.SDATE And FT1.EDATE
And tpos.store_number != 'CMPNY'
)
SELECT * FROM FT2 ORDER BY ITEM_ID
只需使用常规的 GROUP BY 即可减少行数。但是因为我不知道你想要第一个提到的列是什么 table 所以我刚刚发明了 4 作为例子。
WITH
FT1 AS (
SELECT
col1, col2, col3, col4
FROM inv_dtl
WHERE inv_no IN (16084, 23456, 14789)
),
FT3 AS (
SELECT
FT1.col1, FT1.col2, FT1.col3, FT1.col4
, SUM(tpos.quantity) OVER (PARTITION BY tpos.item_id) AS pos_qty
, ROW_NUMBER() OVER (PARTITION BY col1, col2, col3, col4 ASC) +
AS unique_store_cnt
FROM FT1
LEFT JOIN tpos ON tpos.item_id = FT1.ITEM_ID
AND tpos.movement_date BETWEEN FT1.SDATE AND FT1.EDATE
AND tpos.store_number != 'CMPNY'
GROUP BY
FT1.col1, FT1.col2, FT1.col3, FT1.col4
)
SELECT
*
FROM FT3
ORDER BY col1, col2, col3, col4
请注意,如果数据是 "equal rank",RANK()
和 DENSE_RANK()
可以重复数字。要保证每行的唯一整数,请改用 ROW_NUMBER()
。