在 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()