2009-05-13 1 views
0

Ich schreibe einen Bericht und frage mich, ob es eine Möglichkeit gibt, Elemente zu finden, die sich in identische Sets einfügen?Ermitteln von Elementen, die sich mit dem gleichen Set in T-SQL verbinden

Zum Beispiel in der folgenden Abfrage, möchte ich alle Bereiche finden, die mit dem gleichen Satz von Produkten verbinden:

SELECT Area.Name, AggregateSetOfProductsId 
FROM Area 
INNER JOIN AreaToProduct ON AreaToProduct.AreaId = Area.Id 
GROUP BY Area.Id 

Die derzeit beste Lösung, die ich schreibe ein benutzerdefiniertes Aggregat denken könnte, dass die gehasht ProductId Uniqueidentifiers zusammen (so etwas wie Shift rechts basierend auf einem Byte dann xor sie zusammen), aber ich dachte, ich würde fragen, ob es einen einfacheren Weg, bevor es durch.

+0

Was bedeutet "gegen das gleiche"? Sind sie mit den gleichen Produkten verwandt? –

Antwort

1

Sie können dies mit Set-Operationen tun. Hier zeige ich Ihnen, wie alle orderid die von Northwind erhalten, die enthält genau die gleichen Produkte (das ist, was Sie nach, rechts die Bereiche mit genau den gleichen Produkten?)

select distinct o1.orderid 
from orders o1 inner join orders o2 on o1.orderid!=o2.orderid 
where not exists 
    (
     select * from [order details] od2 
     where od2.orderId=o2.Orderid 
      and od2.ProductId NOT IN 
      (
       select productid from [order details] od1 
       where od1.OrderId=o1.OrderId 
      ) 
    ) 
    and not exists 
    (
     select * from [order details] od1 
     where od1.orderId=o1.Orderid 
      and od1.ProductId NOT IN 
      (
       select productid from [order details] od2 
       where od2.OrderId=o2.OrderId 
      ) 
    ) 

Die Idee ist im Grunde diese: Rückkehr Bestellung o1, für die es eine Bestellung o2 gibt, für die es keine Produkte gibt, die nicht in der Liste der Produkte von o1 enthalten sind und in denen keine Produkte von o1 nicht in der Liste der Produkte von o2 enthalten sind.

1

Sie leicht diese mit einem Common Table Expression tun können. Sie würden FOR XML PATH verwenden, um ein Array zu erstellen, und dann dieses Array verwenden, um übereinstimmende Produkte zu identifizieren. So:

;WITH AreaProductSets 
AS 
(
SELECT a.AreaID, a.Name, 
       SUBSTRING((SELECT (', ' + CAST(ap.ProductID AS varchar(20))) 
            FROM AreaToProduct ap 
            WHERE ap.AreaID = a.AreaID 
            ORDER BY ap.ProductID 
            FOR XML PATH ('')), 3, 2000) AS ProductArray 
FROM  Area AS a 
) 
SELECT SUBSTRING((SELECT (', ' + CAST(aps2.Name AS varchar(20))) 
            FROM  AreaProductSets aps2 
            WHERE aps2.ProductArray = aps.ProductArray 
            ORDER BY aps2.AreaID 
            FOR XML PATH('')), 3, 2000) AS MatchingAreas, 
       aps.ProductArray 
FROM  (SELECT DISTINCT ProductArray FROM AreaProductSets) AS aps 
Verwandte Themen