T-SQL:如何将项目集与事务列表匹配?

时间:2014-09-03 17:54:55

标签: sql sql-server tsql

我有一个带有项目列表(=事务)的表,第二个带有子组的项目(=项目集)。 结果,我需要一个新表(=结果集),显示包含表' itemset'中所有项目的所有交易,例如项目' a'和' f'是交易1和5的一部分,' a'是交易1,2,4,5的一部分......等等。

如何使用T-SQL解决这个问题?

table1:transactions

TID            itemlist   
1              a,c,f
2              a
3              c,f,g,h,l
4              b,a,c
5              f,a  

table2:itemset

SID            item1   item2   item3 ......... item n 
1              a
2              c       l
3              c       f       l 
4              a       f 

结果集:

SID   TID
1     1
1     2
1     4
1     5
2     3
3     3
4     1
4     5    

2 个答案:

答案 0 :(得分:0)

这不符合评论,但作为Abe意味着什么的一个例子。如果您有两个表TransItem和ItemSet,如下所示:

TID     ItemId
1       a
1       c
1       f
2       a

SID     ItemID
1       a
2       c
2       l

然后,结果集只是设置项与交易项

的比较
with SetItems
    as (select sid
                ,  count(sid) as itemcount 
        from ItemSet 
        group by sid)
, TransSet as (
        Select tid
                , sid
                , count(tid) transcount
        from 
            ItemSet s INNER JOIN 
            TransItem t ON s.Itemid=t.Itemid
        group by sid, tid )
Select s.sid, t.tid
from SetItems s LEFT OUTER JOIN 
TransSet t on s.sid=t.sid
where itemcount=transcount
order by sid, tid

毋庸置疑,如果你有列中的项目或逗号分隔的字段,这个查询会变得更加困难。

答案 1 :(得分:0)

分割功能

CREATE FUNCTION [dbo].[split]  
    (  
      @delimited NVARCHAR(MAX),  
      @delimiter NVARCHAR(100)  
    )   
 RETURNS @t TABLE (id INT IDENTITY(1,1), val NVARCHAR(MAX))  
AS  
BEGIN  
  DECLARE @xml XML  
  SET @xml = N'<t>' + REPLACE(@delimited,@delimiter,'</t><t>') + '</t>'  

  INSERT INTO @t(val)  
  SELECT  r.value('.','varchar(MAX)') as item  
  FROM  @xml.nodes('/t') as records(r)  
  RETURN  
END

测试数据

CREATE TABLE #transactions  (TID INT, itemlist VARCHAR(100))
INSERT INTO #transactions VALUES   
(1 ,'a,c,f'),
(2 ,'a'),
(3 ,'c,f,g,h,l'),
(4 ,'b,a,c'),
(5 ,'f,a')

CREATE TABLE #itemset([SID] INT, item1 VARCHAR(1), item2 VARCHAR(1), item3 VARCHAR(1))
INSERT INTO #itemset VALUES
(1 ,'a', NULL,  NULL),
(2 ,'c', 'l' ,  NULL),
(3 ,'c', 'f' ,  'l' ),
(4 ,'a', NULL,  'f') 

查询

;WITH TIDs AS (
    SELECT t.TID
          ,c.Items
    FROM #transactions t
           CROSS APPLY (SELECT Val FROM dbo.Split(t.itemlist , ',')) c(Items)
  ),
SIDs AS (
    SELECT [SID]
           ,Items
    FROM #itemset t
     UNPIVOT ( Items FOR item IN (item1,item2,item3)) up
  )
SELECT S.[SID]
      ,T.[TID]
FROM TIDs T INNER JOIN SIDs S 
ON T.Items = S.Items

结果

╔═════╦═════╗
║ SID ║ TID ║
╠═════╬═════╣
║   1 ║   1 ║
║   1 ║   2 ║
║   1 ║   4 ║
║   1 ║   5 ║
║   2 ║   1 ║
║   2 ║   3 ║
║   2 ║   4 ║
║   2 ║   3 ║
║   3 ║   1 ║
║   3 ║   3 ║
║   3 ║   4 ║
║   3 ║   1 ║
║   3 ║   3 ║
║   3 ║   5 ║
║   3 ║   3 ║
║   4 ║   1 ║
║   4 ║   2 ║
║   4 ║   4 ║
║   4 ║   5 ║
║   4 ║   1 ║
║   4 ║   3 ║
║   4 ║   5 ║
╚═════╩═════╝