Utiliser Firebird, j'ai deux tables, Orders
et DespatchedParts
.
Orders
Table:
ID CustomerID Total_number_parts
-- ---------- ------------------
1 1 5
2 1 4
3 2 10
4 1 5
5 3 20
DespatchedParts
Table:
ID OrdersID PartQty
-- -------- -------
1 1 2
2 1 3
3 2 10
4 3 10
5 3 10
Donc, dans la table Orders
la somme de Total_number_parts
pour les commandes de 1 + 4 + 5 = 14.
Puis cherche dans DespatchedParts
, nous voulons la somme de PartQty
pour le client 1, donc 2 + 3 = 5.
Donc, le client 1 a commandé 14 parties et 5 ont été expédiés. Je veux obtenir tous les identifiants du client qui ont reçu toutes leurs parties.
Vous trouverez ci-dessous ce que j'ai jusqu'à présent. Je ne sais pas où mettre la partie 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
Vous souhaitez sélectionner tous les clients dont les commandes ont été complètement remplies. Ainsi, vous devez d'abord savoir combien de pièces commandées au total au total:
select customerid, sum(total_number_parts) ordered
from orders
group by customerid
Vous devez également savoir combien de pièces ont été expédiées pour chaque client. Vous devrez rejoindre des commandes et des pièces expédiées pour obtenir le CustomerID associé aux pièces expédiées.
select o.customerid, sum(dp.partqty) dispatched
from orders o
left join dispatched_parts dp
on dp.ordersid = o.id
group by o.customerid
J'utilise une jointure gauche ici, vous obtenez donc également la quantité totale si aucune pièce n'a été envoyée. Cela n'est pas nécessaire pour votre question, mais devient pertinente si vous souhaitez obtenir tous les clients qui n'ont pas encore reçu leurs pièces.
Nous combinons ces deux et appliquons la condition demandée dans la clause où:
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
En supposant les ordonnations corrigées (1, 1, 3, 5, 5), j'ai suggéré dans les commentaires, ces rendements
customerid
2
3
Sinon, vous pouvez déplacer entièrement la deuxième partie dans la clause WHERE en le faisant une sous-requête corrélée:
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
)
Configurer les données de test:
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)
Solution:
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
Je remarquai seulement que c'était pour Firebird à partir de tout ce qui est désolé si cela ne fonctionne pas. Vous pouvez aussi faire:
SELECT o.*
FROM #order o
WHERE o.total_number_parts = (SELECT SUM(partqty) FROM #despatchedparts d WHERE o.id = d.ordersid)