聚合问题具有连接和父子级别的mssql

时间:2016-04-12 17:02:10

标签: sql-server join aggregate parent-child

源表示例

Table1
id      id_parent   product_id    
===     =========   ========    
154     104389        1043891       
155     104389        1995137331       

然后我有两个其他库存表如下:

(table2)
product_id   location_id       on_hand     transit
1043891          2           12      1
1043891          5           33      0
1043891          6           7       0
1043891          4           3       0
1995137331       2           8       5
1995137331       8           50      9
1995137331       5           95      0
1995137331       11          22      5
1995137331       13          93      1

(table3)
product_id   location_id    on_hand      transit
1043891           1         25       1
1995137331        1         29       0

我有以下查询:

; with 
O as (select Product_Id, SUM(OnHand) AS AllStore from Table2 group by Product_Id),
S as (select Product_Id, SUM(OnHand) as WH from Table3 group by Product_Id)

SELECT
   L1.id_parent as parent
  ,L1.product_id as child
  , O.AllStore
  , S.WH
FROM Table1 L0 JOIN Table1 L1 ON L0.id_parent = L1.id_parent 

LEFT OUTER JOIN S on S.Product_ID = L0.Product_Id
LEFT OUTER JOIN O on O.Product_ID = L0.Product_ID
group by L1.id_parent, L1.product_id, S.WH, O.AllStore

它有点工作,但重复记录。目前的结果:

parent  child       AllStore    WH
1043892 1043891     104         102
1043892 1043891     242         123
1043892 1995137331  104         102
1043892 1995137331  242         123

预期结果:

parent  child       AllStore    WH
1043892 1043891     104         102
1043892 1995137331  242         123

有人可以看看它,看看我做错了什么,或者是否有更好的方法。

感谢。

1 个答案:

答案 0 :(得分:1)

问题来自于您将Table1加入到

的条件下
L0.id_parent = L1.id_parent 

这种连接有效地将表1中的2行104389与2行连接起来。此连接条件将产生4行。

SELECT
   *
FROM 
    @Table1 L0
    INNER JOIN @Table1 L1 ON
        L0.id_parent = L1.id_parent

id          id_parent   product_id  id          id_parent   product_id
----------- ----------- ----------- ----------- ----------- -----------
154         104389      1043891     154         104389      1043891
154         104389      1043891     155         104389      1995137331
155         104389      1995137331  154         104389      1043891
155         104389      1995137331  155         104389      1995137331

根据您提供的示例,此连接完全没必要,因为您需要的数据已经在L0

由于您没有运行任何聚合,因此group by语句也是不必要的。将其保留的最终结果与在整个查询中放置DISTINCT相同。

因此:产生所描述的“预期结果” 查询可以修改为以下

; with 
O as (select Product_Id, SUM(on_hand) AS AllStore from @Table2 group by Product_Id),
S as (select Product_Id, SUM(on_hand) as WH from @Table3 group by Product_Id)

SELECT
   L0.id_parent as parent
  ,L0.product_id as child
  ,O.AllStore
  ,S.WH
FROM
    @Table1 L0

    LEFT OUTER JOIN S ON
        S.Product_ID = L0.Product_Id

    LEFT OUTER JOIN O ON
        O.Product_ID = L0.Product_ID

注意:如果L0和L1连接是拼写错误,并且有第4个表正在播放但仍然产生重复,则可以将L0和L1连接提取到子查询中并对其进行DISTINCT。