【问题标题】:SQL Select joining three tables and group bySQL Select 连接三个表并分组
【发布时间】:2015-08-28 15:05:06
【问题描述】:

我正在尝试创建一个 SQL Select,它将查找表 #Parts 中的所有行,其中 #Parts.on_order 列中的值与实际的订购数量不匹配。这是示例。三个表:Parts、Orders 和 Receives。

IF OBJECT_ID(N'tempdb..#Parts') IS NOT NULL
BEGIN
 DROP TABLE #Parts
END
IF OBJECT_ID(N'tempdb..#orders') IS NOT NULL
BEGIN
 DROP TABLE #orders
END
IF OBJECT_ID(N'tempdb..#received') IS NOT NULL
BEGIN
  DROP TABLE #received
END

create table #Parts (part_no char(25), part_pk int, on_order decimal(12,2))
insert into #Parts (part_no, part_pk, on_order) values ('ABC1', 1, 19)
insert into #Parts (part_no, part_pk, on_order) values ('ABC2', 2, 2)
insert into #Parts (part_no, part_pk, on_order) values ('ABC3', 3, 0)

create table #orders (po_order_no int, part_no char(25), part_pk int,     qty_ordered decimal(12,2))
 insert into #orders (po_order_no, part_no, part_pk, qty_ordered) values (1, 'ABC2', 2, 10)
 insert into #orders (po_order_no, part_no, part_pk, qty_ordered) values (2, 'ABC2', 2, 1)
 insert into #orders (po_order_no, part_no, part_pk, qty_ordered) values 
 (3, 'ABC2', 2, 4   )
  insert into #orders (po_order_no, part_no, part_pk, qty_ordered) values (4, 'ABC1', 1, 20)
 insert into #orders (po_order_no, part_no, part_pk, qty_ordered) values (5, 'ABC1', 1, 6)
insert into #orders (po_order_no, part_no, part_pk, qty_ordered) values (6, 'ABC3', 3, 7)

create table #received (po_order_no int, qty_received decimal(12,2))
insert into #received (po_order_no, qty_received) values (2, 1)
insert into #received (po_order_no, qty_received) values (3, 2)
insert into #received (po_order_no, qty_received) values (4, 3)
insert into #received (po_order_no, qty_received) values (4, 2)
insert into #received (po_order_no, qty_received) values (5, 2)
insert into #received (po_order_no, qty_received) values (6, 7)

我厌倦了以下 SQL Select 但它甚至在 ORDERED 列中给了我一个错误的值:

select 
    MAX(#Parts.part_no), SUM(#received.qty_received) as RECEIVED, 
    SUM(#orders.qty_ordered) as ORDERED 
from 
    #received 
join 
    #orders on #orders.po_order_no = #received.po_order_no 
join 
    #Parts on #Parts.part_pk = #orders.part_pk 
group by 
    #Parts.part_pk, #orders.po_order_no

我错过了什么?

【问题讨论】:

    标签: sql sql-server


    【解决方案1】:

    您需要考虑这样一个事实,即收到的表可以有多个记录与一个订单相关联。因此,您必须先聚合 qty_received 数据,然后再将其与订单表连接,以消除重复订单的聚合:

    SELECT
        MAX(p.part_no)
        ,SUM(r.qty_received) as RECEIVED
        ,SUM(o.qty_ordered) as ORDERED
        ,SUM(o.qty_ordered) - SUM(r.qty_received) AS [DIFFERENCE]
    FROM #parts AS p
    JOIN #orders AS o on o.part_pk = p.part_pk
    JOIN 
    (   SELECT
            po_order_no
            ,SUM(qty_received) AS qty_received
        FROM #received
        GROUP BY po_order_no
    ) AS r on r.po_order_no = o.po_order_no
    GROUP BY p.part_pk, o.po_order_no
    

    【讨论】:

    • 感谢您的帮助。是的,现在,您的 SQL Select 正确显示了 Received 和 Ordered。我如何(在同一个 SQL 选择中)将 Ordered 和 Received 之间的差异与 #Parts.on_order 的值进行比较?
    • 您可以在选择查询中添加一行:,SUM(o.qty_ordered) - SUM(r.qty_received) AS [DIFFERENCE]。请参阅上面的更新帖子。
    • 扎克,非常感谢。但是现在我试过了,[DIFFERENCE] 显示了每个订单的差异。我正在尝试根据#Parts 中的值查看所有订单的总 [DIFFERENCE]。
    • 从末尾的GROUP BY 子句中删除, o.po_order_no
    【解决方案2】:

    创建表格:

    --add # to create a temp table
    CREATE TABLE Parts (
    part_no CHAR(25)
    ,part_pk INT
    ,on_order DECIMAL(12, 2)
    );
    
    insert into Parts (part_no, part_pk, on_order) values 
    ('ABC1', 1, 19),
    ('ABC2', 2, 2),
    ('ABC3', 3, 0)
    
    --add # to create a temp table
    CREATE TABLE orders (
    po_order_no INT
    ,part_no CHAR(25)
    ,part_pk INT
    ,qty_ordered DECIMAL(12, 2)
    );
    
    insert into orders (po_order_no, part_no, part_pk, qty_ordered) values 
    (1, 'ABC2', 2, 10),
    (2, 'ABC2', 2, 1),
    (3, 'ABC2', 2, 4),
    (4, 'ABC1', 1, 20),
    (5, 'ABC1', 1, 6),
    (6, 'ABC3', 3, 7)
    
    --add # to create a temp table
    CREATE TABLE received (
    po_order_no INT
    ,qty_received DECIMAL(12, 2)
    );
    
    insert into  received (po_order_no, qty_received) values 
    (2, 1),
    (3, 2),
    (4, 3),
    (4, 2),
    (5, 2),
    (6, 7)
    

    选择声明:

    SELECT p.part_no
        ,SUM(r.qty_received) AS RECEIVED
        ,SUM(o.qty_ordered) AS ORDERED
        ,SUM(o.qty_ordered) - SUM(r.qty_received) AS Total_Difference
    FROM (
        SELECT po_order_no
            ,sum(qty_received) AS qty_received
        FROM received
        GROUP BY po_order_no
        ) r
    INNER JOIN orders o ON o.po_order_no = r.po_order_no
    INNER JOIN parts p ON p.part_pk = o.part_pk
    GROUP BY p.part_no, p.on_order --just need to group by part_no, on_order
        --HAVING SUM(r.qty_received) <> SUM(o.qty_ordered) --optional filter 
    ORDER BY p.part_no
    

    结果:

    +---------+----------+---------+------------------+
    | part_no | RECEIVED | ORDERED | Total_Difference |
    +---------+----------+---------+------------------+
    | ABC1    |        7 |      26 |               19 |
    | ABC2    |        3 |       5 |                2 |
    | ABC3    |        7 |       7 |                0 |
    +---------+----------+---------+------------------+
    

    SQL Fiddle Demo

    【讨论】:

    • FutbolFan,非常感谢。你走近的作品也。但是我对 SQL Select 的了解还不够,无法决定哪个更有效率,你的还是 Allen 先生的。 Buena suerte a Barça :)
    猜你喜欢
    • 2021-03-19
    • 1970-01-01
    • 2020-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-09
    相关资源
    最近更新 更多