web-dev-qa-db-ja.com

2つの選択結果の合計を比較する

Firebirdを使用すると、OrdersDespatchedPartsの2つのテーブルがあります。

Ordersテーブル:

_ID  CustomerID  Total_number_parts
--  ----------  ------------------
1   1           5
2   1           4
3   2           10
4   1           5
5   3           20
_

DespatchedPartsテーブル:

_ID  OrdersID  PartQty
--  --------  -------
1   1         2
2   1         3
3   2         10
4   3         10
5   3         10
_

したがって、Ordersテーブルでは、顧客1の注文の_Total_number_parts_の合計は5 + 4 + 5 = 14です。

次に、DespatchedPartsを調べて、顧客1のPartQtyの合計が必要なので、2 + 3 = 5にします。

したがって、顧客1は14個の部品を注文し、5個が発送されました。すべてのパーツを受け取ったお客様IDをすべて取得したい。

以下は私が今までに得たものです。 sum(total_number_parts) = sum(qtyparts)部分をどこに置くかわかりません。

_Select a.customerID, sum(a.Total_number_parts)
From Orders a
Join (Select sum(PartQty) from OrderParts Group by customerID) B
   on B.customerID = a.customerID
Group By a.CustomerID
_
2
Simon

注文が完全に満たされているすべての顧客を選択するとします。したがって、最初に、顧客が注文した部品の総数を知る必要があります。

select customerid, sum(total_number_parts) ordered
from orders
group by customerid

また、顧客ごとに出荷された部品の数を知る必要もあります。発送されたパーツに関連付けられているカスタマーIDを取得するには、注文と発送されたパーツを結合する必要があります。

select o.customerid, sum(dp.partqty) dispatched
from orders o 
left join dispatched_parts dp
   on dp.ordersid = o.id 
group by o.customerid

ここでは左結合を使用しているため、パーツがまだ発送されていない場合も合計数を取得できます。これはあなたの質問には必要ありませんが、まだすべての部品を受け取っていないすべての顧客を獲得したい場合に関連します。

これら2つを組み合わせて、要求された条件をwhere節に適用します。

select a.customerid
from (
    select customerid, sum(total_number_parts) ordered
    from orders
    group by customerid
) a
inner join (
    select o.customerid, sum(dp.partqty) dispatched
    from orders o 
    left join dispatched_parts dp
       on dp.ordersid = o.id 
    group by o.customerid
) b on b.customerid = a.customerid
where ordered = dispatched

私がコメントで提案した修正された注文ID(1、1、3、5、5)を仮定すると、これは

customerid
2
3

または、2番目の部分を相関サブクエリにして、where句に完全に移動することもできます。

select a.customerid
from (
    select customerid, sum(total_number_parts) ordered
    from orders
    group by customerid
) a
where a.ordered = (
    select sum(dp.partqty) 
    from orders o 
    left join dispatched_parts dp
       on dp.ordersid = o.id 
    where o.customerid = a.customerid
)
2
Mark Rotteveel

テストデータを設定します。

CREATE TABLE #order (id INT, customerid INT, total_number_parts INT)
INSERT INTO #order ( id ,customerid ,total_number_parts)VALUES  ( 1,1,5)
INSERT INTO #order ( id ,customerid ,total_number_parts)VALUES  ( 2,1,4)
INSERT INTO #order ( id ,customerid ,total_number_parts)VALUES  ( 3,2,10)
INSERT INTO #order ( id ,customerid ,total_number_parts)VALUES  ( 4,1,50)
INSERT INTO #order ( id ,customerid ,total_number_parts)VALUES  ( 5,3,20)

CREATE TABLE #despatchedparts (id INT, ordersid INT, partqty int)
INSERT INTO #despatchedparts (id, ordersid, partqty) VALUES (1,1,2)
INSERT INTO #despatchedparts (id, ordersid, partqty) VALUES (2,1,3)
INSERT INTO #despatchedparts (id, ordersid, partqty) VALUES (3,2,10)
INSERT INTO #despatchedparts (id, ordersid, partqty) VALUES (4,3,10)
INSERT INTO #despatchedparts (id, ordersid, partqty) VALUES (5,3,10)

解決:

SELECT o.id AS [OrderId], o.customerid AS [CustomerId], o.total_number_parts AS [Parts orded], SUM(d.partqty) AS [Parts sent],
    CASE WHEN o.total_number_parts = SUM(d.partqty) THEN 'All delivered'
    WHEN SUM(d.partqty) = 0 THEN 'None delivered'
    ELSE 'Part delivered' END AS [Status]
FROM #order o
LEFT outer JOIN #despatchedparts d ON o.id = d.ordersid
GROUP BY o.id, o.customerid, o.total_number_parts

これがFirebirdの途中であることに気付いただけで、それが機能しない場合は申し訳ありません。あなたも行うことができます:

SELECT o.*
FROM #order o
WHERE o.total_number_parts = (SELECT SUM(partqty) FROM #despatchedparts d WHERE o.id = d.ordersid)
0
Paul