确定在T-SQL中针对同一集合加入的项目

时间:2009-05-13 02:49:51

标签: sql sql-server tsql join set

我正在写一份报告,并想知道是否有办法找到加入相同集合的项目?

例如,在以下查询中,我想查找针对同一组产品加入的所有区域:

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

我能想到的当前最佳解决方案是编写一个将ProductId uniqueidentifiers混合在一起的自定义聚合(类似于基于某个字节的移位,然后将它们放在一起)但是我想我会问是否更容易在经历之前的方式。

3 个答案:

答案 0 :(得分:1)

您可以使用Common Table Expression轻松完成此操作。您将使用FOR XML PATH创建一个数组,然后使用该数组来标识匹配的产品。像这样:

;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

答案 1 :(得分:1)

您可以使用设置操作执行此操作。在这里,我向您展示如何从northwind获得所有包含完全相同产品的orderid(这是您所追求的,对吧?具有完全相同产品的区域)

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
            )
    )

这个想法基本上是这样的:返回订单o1,其中存在订单o2,其中没有任何产品不在o1的产品列表中,并且没有任何来自o1的产品不在产品列表中of o2。

答案 2 :(得分:0)

也许使用EXCEPT运算符?如果两组之间的EXCEPT为空,则这些组是相同的。见http://msdn.microsoft.com/en-us/library/ms188055.aspx 此外,要散列结果集,您可以使用内置聚合,如CHECKSUM_AGG(BINARY_CHECKSUM(*)),请参阅http://msdn.microsoft.com/en-us/library/ms188920.aspx