组合多行数据

时间:2015-05-21 15:40:12

标签: sql sql-server

我有3个表我正在编写查询:Memos,Memos_Description,Policies。数据库不是我自己设计的,我无法改变它,这只是一个报告。

我目前有一个似乎有效的查询,但在加入我需要的额外表之前效率极低。

SELECT
    Main.CLIENTSNAME,
    Main.ENTRYDATE,
    Main.AUTHOR,
    Main.POLICYNUMBER,
    Main.CLIENTS_ID,
    Main.MEMOS_ID,
    Left(Main.DESCRIPTION,Len(Main.DESCRIPTION)) AS REGARDING
FROM
    (
        SELECT distinct ST1.MEMOS_ID, 
            (
                SELECT ST2.DESCRIPTION + ' ' AS [text()]
                FROM dbo.MEMOS_DESCRIPTION ST2
                WHERE ST1.MEMOS_ID = ST2.MEMOS_ID
                ORDER BY ST1.MEMOS_ID
                For XML PATH ('')
            ) [DESCRIPTION],
            ST1.CLIENTSNAME,
            ST1.ENTRYDATE,
            ST1.AUTHOR,
            ST1.POLICYNUMBER,
            ST1.REGARDING,
            ST1.CLIENTS_ID
        FROM dbo.MEMOS ST1
    ) [Main]

表格如下:

tbl.MEMOS
MEMOS_ID
POLICIES_ID
CLIENTSNAME

tbl.MEMOS_DESCRIPTION
MEMOS_ID
DESCRIPTION

tbl.POLICIES
POLICIES_ID
POLICYNUMBER

数据如下所示:

tbl1.MEMOS_ID | tbl1.CLIENTSNAME
1                PERSON ONE
2                PERSON TWO
3                PERSON THREE

tbl2.MEMOS_ID | tbl2.DESCRIPTION
1               This is a sentence
1               that can run over more
1               than one description record.
2               Person two has
2               something different.
3               Client Created.

tbl3.POLICIES_ID | tbl3.POLICYNUMBER
123                ABCDE
456                FGHIJ

我希望报告看起来像:

tbl1.MEMOS_ID | tbl1.CLIENTSNAME | tbl2.DESCRIPTION                                                            | tbl3.POLICIES_ID | tbl3.POLICYNUMBER
1               PERSON ONE         This is a sentence that can run over more tan one description record.         123                ABCDE

我希望这是有道理的,谢谢你。

根据Gordon建议的答案更新了查询:

SELECT ST1.*, 
    STUFF(
        (SELECT ' ' + ST2.DESCRIPTION AS [text()] 
            FROM dbo.MEMOS_DESCRIPTION ST2 
            WHERE ST1.MEMOS_ID = ST2.MEMOS_ID 
            ORDER BY ST1.MEMOS_ID 
            For XML PATH ('')
        ), 1, 1, '') [REGARDING] 
FROM 
    (SELECT DISTINCT ST1.MEMOS_ID,
        ST1.CLIENTSNAME,
        ST1.ENTRYDATE,
        ST1.AUTHOR,
        ST1.POLICYNUMBER,
        ST1.CLIENTS_ID,
        ST1.POLICIES_ID 
    FROM dbo.MEMOS ST1
    ) ST1 

LEFT JOIN POLICIES B 
    ON ST1.POLICIES_ID = B.POLICIES_ID 

WHERE ST1.ENTRYDATE >= DATEADD(month, -2, GETDATE()) 
    AND (B.PROD1 = ('123') OR B.PROD1 = ('456') OR B.PROD1 = ('789'))

1 个答案:

答案 0 :(得分:1)

如果在进行字符串聚合之前执行select distinct ,性能如何比较?

    SELECT ST1.*, 
           STUFF((SELECT ' ' + ST2.DESCRIPTION AS [text()]
                  FROM dbo.MEMOS_DESCRIPTION ST2
                  WHERE ST1.MEMOS_ID = ST2.MEMOS_ID
                  ORDER BY ST1.MEMOS_ID
                  For XML PATH ('')
                 ), 1, 1, '') ) [DESCRIPTION]
    FROM (SELECT DISTINCT T1.MEMOS_ID, ST1.CLIENTSNAME, ST1.ENTRYDATE,
                 ST1.AUTHOR, ST1.POLICYNUMBER, ST1.REGARDING, ST1.CLIENTS_ID
          FROM dbo.MEMOS ST1
         ) ST1

我怀疑SQL Server可能在运行distinct之前为每一行执行字符串聚合 - 这是很多不必要的工作。