在for xml路径中使用distinct而不包括select

时间:2013-08-12 15:54:36

标签: sql-server-2008 tsql for-xml-path

顶部查询在一个表中查找每个语句只有一个记录,因此如果客户有7个语句,则行数应为7,查询将列出它们,如1,2,3,4, 5,6,7

底部查询在一个表中查找将具有如上所述的7个语句,但更多时候,它们将被拆分,因此如果每个语句有2行,则会有14个,即1,1,2 ,2,3,3,4,4,5,5,6,6,7,7

现在,我想要实现的目标如下,顶层查询很好,但底层查询需要区分。看看底部图像的结果编号2,我希望它以1,2,3,4,5,6,7,8,9,10的形式返回。

如果有一个特定的实例声明分别达到8和4,我会想要1,2,3,4,5,6,7,8。基本上它在大多数情况下复制底部查询的语句数字,我希望它只是在整个结果中做一个明显的整体,但是我尝试了一个明显的并且它抱怨按项目的顺序必须包含在选择中声明如果包含在一个不同的内容中,这会破坏我的疑问。

这两个查询的最终目的是将顶部结果集与底部进行比较,并仅返回不匹配的结果集(因为这意味着我在顶部查询表中缺少一个语句)

--Shows the each consolidated statement number that exisits for that particular customer reference number within the dbo.rss table.

Select Main.cust_ref,
       Left(CAST(Main.consolidatedstatements as varchar(max)),Len(CAST(Main.consolidatedstatements as varchar(max)))-1) As "consolidatedstatements"
From(Select distinct ST2.cust_ref, 
           (Select CAST(ST1.consolidated_stmt_num as varchar(max)) + ',' AS [text()]
            From dbo.rss ST1
            Where ST1.cust_ref = ST2.cust_ref
            ORDER BY ST1.cust_ref
            For XML PATH ('')) [consolidatedstatements]
     From dbo.rss ST2) [Main]


--Shows the each consolidated statement number that exisits for that particular customer reference number within the dbo.SC table.
Select Main.cust_ref,
       Left(CAST(Main.consolidatedstatements as varchar(max)),Len(CAST(Main.consolidatedstatements as varchar(max)))-1) As "consolidatedstatements"
From(Select distinct ST2.cust_ref, 
           (Select  CAST(ST1.consolidated_stmt_num as varchar(max)) + ',' AS [text()]
            From dbo.SC ST1
            Where ST1.cust_ref = ST2.cust_ref
            ORDER BY ST1.cust_ref
            For XML PATH ('')) [consolidatedstatements]
     From dbo.SC ST2) [Main]

enter image description here

1 个答案:

答案 0 :(得分:2)

CREATE TABLE #rss(cust_ref VARCHAR(32), consolidated_stmt_num INT);

CREATE TABLE #SC(cust_ref VARCHAR(32), consolidated_stmt_num INT);

INSERT #SC VALUES
('A',1),('A',2),('A',3),('A',4),('A',5),('A',6),('A',7),('A',8),('A',9),
('B',1),('B',2),('B',3),('B',4),('B',5),('B',6),('B',7),('B',8),('B',9),
('C',1),('C',2),('C',3),('C',4),('C',5),('C',6),('C',7),('C',8),('C',9);

-- missing A,7 and C,2/C,4:
INSERT #rss VALUES
('A',1),('A',2),('A',3),('A',4),('A',5),('A',6),        ('A',8),('A',9),
('B',1),('B',2),('B',3),('B',4),('B',5),('B',6),('B',7),('B',8),('B',9),
('C',1),        ('C',3),        ('C',5),('C',6),('C',7),('C',8),('C',9);

GO

- 仅此一项将告诉您缺少语句的cust_refs(以及它们是哪些):

SELECT cust_ref, consolidated_stmt_num FROM #SC
EXCEPT
SELECT cust_ref, consolidated_stmt_num FROM #rss;

- 这将允许您从一个表中获取每个表的完整连接列表:

;WITH x AS
(
  SELECT DISTINCT cust_ref FROM 
  (
    SELECT cust_ref, consolidated_stmt_num FROM #SC
    EXCEPT
    SELECT cust_ref, consolidated_stmt_num FROM #rss
  ) AS y
)
SELECT x.cust_ref, 
    rss = STUFF((SELECT ',' + CONVERT(VARCHAR(12), r.consolidated_stmt_num) 
      FROM #rss AS r WHERE r.cust_ref = x.cust_ref
      ORDER BY r.cust_ref
    FOR XML PATH(''), TYPE).value('.[1]','varchar(max)'),1,1,''),
    sc =  STUFF((SELECT ',' + CONVERT(VARCHAR(12), s.consolidated_stmt_num)
      FROM #SC  AS s WHERE s.cust_ref = x.cust_ref
      ORDER BY s.cust_ref
    FOR XML PATH(''), TYPE).value('.[1]','varchar(max)'),1,1,'')
FROM x;

- 如果您需要在不同的行上:

;WITH x AS
(
  SELECT DISTINCT cust_ref FROM 
  (
    SELECT cust_ref, consolidated_stmt_num FROM #SC
    EXCEPT
    SELECT cust_ref, consolidated_stmt_num FROM #rss
  ) AS y
)
SELECT x.cust_ref, source = 'rss',
    list = STUFF((SELECT ',' + CONVERT(VARCHAR(12), r.consolidated_stmt_num) 
      FROM #rss AS r WHERE r.cust_ref = x.cust_ref
      ORDER BY r.cust_ref
    FOR XML PATH(''), TYPE).value('.[1]','varchar(max)'),1,1,'')
    FROM x
UNION ALL SELECT x.cust_ref, 'sc',
    list = STUFF((SELECT ',' + CONVERT(VARCHAR(12), s.consolidated_stmt_num)
      FROM #SC  AS s WHERE s.cust_ref = x.cust_ref
      ORDER BY s.cust_ref
    FOR XML PATH(''), TYPE).value('.[1]','varchar(max)'),1,1,'')
    FROM x
ORDER BY cust_ref, source;

- 清理:

DROP TABLE #rss, #SC;