How to join CTE query with another table in SQL Server 2008

丶灬走出姿态 提交于 2020-01-07 04:25:10

问题


I have created a CTE query, and I manage to join the CTE when the data in CTE is match with another table.

For example, this is how my CTE query result looks like:

ID     NAME    REG      INV      CUS       BR
-----------------------------------------------
1     A0001   R0001    I0001    C0001     B0001
2     A0002   R0002    I0002    C0002     B0002
3     A0003   R0003    I0003    C0003     B0003
4     A0004   R0004    I0004    C0004     B0004

And this is the table I manage to join it to:

ID    NAME     CUS 
---------------------
1     TEST1   C0001
2     TEST2   C0002
3     TEST3   C0003
4     TEST4   C0004

And this is my code to select CTE query

;WITH BaseQuery AS 
(
    SELECT  
        Id, Name, Comment, 
        CONVERT(XML, '<root><item>' 
                + REPLACE(
                    REPLACE(
                        REPLACE(
                            REPLACE((SELECT Comment AS '*' FOR XML PATH('')), 
                            'Reg:', 
                            '</item><item type="Reg">'), 
                        'Inv:', 
                        '</item><item type="Inv">'), 
                    'Cus:', 
                    '</item><item type="Cus">'), 
                'Br:', 
                '</item><item type="Br">') + '</item></root>') CommentAsXml
    FROM    
        GenTransaction
), Query (
SELECT  
    Id, Name, Comment, 
    Reg = LTRIM(RTRIM(bq.CommentAsXml.value('(root/item[@type="Reg"])[1]', 'VARCHAR(11)'))),
    Inv = LTRIM(RTRIM(bq.CommentAsXml.value('(root/item[@type="Inv"])[1]', 'VARCHAR(11)'))),
    Cus = LTRIM(RTRIM(bq.CommentAsXml.value('(root/item[@type="Cus"])[1]', 'VARCHAR(11)'))),
    Br  = LTRIM(RTRIM(bq.CommentAsXml.value('(root/item[@type="Br"])[1]', 'VARCHAR(11)'))) 
FROM    
    BaseQuery bq
)

select ArCustomer.Name, Query.Cus from ArCustomer left join Query on ArCustomer.Customer = Query.ArCustomer.Customer order by ArCustomer.Name


回答1:


[ 1 ] Using two CTEs (BaseQuery, Query and join between table and Query):

;WITH BaseQuery AS 
(
    SELECT  
        Id, Name, Comment, 
        CONVERT(XML, '<root><item>' 
                + REPLACE(
                    REPLACE(
                        REPLACE(
                            REPLACE((SELECT Comment AS '*' FOR XML PATH('')), 
                            'Reg:', 
                            '</item><item type="Reg">'), 
                        'Inv:', 
                        '</item><item type="Inv">'), 
                    'Cus:', 
                    '</item><item type="Cus">'), 
                'Br:', 
                '</item><item type="Br">') + '</item></root>') CommentAsXml
    FROM    
        GenTransaction
), Query (
SELECT  
    Id, Name, Comment, 
    Reg = LTRIM(RTRIM(bq.CommentAsXml.value('(root/item[@type="Reg"])[1]', 'VARCHAR(11)'))),
    Inv = LTRIM(RTRIM(bq.CommentAsXml.value('(root/item[@type="Inv"])[1]', 'VARCHAR(11)'))),
    Cus = LTRIM(RTRIM(bq.CommentAsXml.value('(root/item[@type="Cus"])[1]', 'VARCHAR(11)'))),
    Br  = LTRIM(RTRIM(bq.CommentAsXml.value('(root/item[@type="Br"])[1]', 'VARCHAR(11)'))) 
FROM    
    BaseQuery bq
)
SELECT ...
FROM Table1 t1 INNER/LEFT OUTER/... JOIN Query q ON ... join condition ... -- Query represents the second CTE
ORDER BY ...

[ 2 ] Second solution is based also on two CTEs (BaseQuery and Query) but instead of JOIN is using APPLY operator thus:

;WITH BaseQuery AS 
(
    SELECT  
        Id, Name, Comment, 
        CONVERT(XML, '<root><item>' 
                + REPLACE(
                    REPLACE(
                        REPLACE(
                            REPLACE((SELECT Comment AS '*' FOR XML PATH('')), 
                            'Reg:', 
                            '</item><item type="Reg">'), 
                        'Inv:', 
                        '</item><item type="Inv">'), 
                    'Cus:', 
                    '</item><item type="Cus">'), 
                'Br:', 
                '</item><item type="Br">') + '</item></root>') CommentAsXml
    FROM    
        GenTransaction
), Query (
SELECT  
    Id, Name, Comment, 
    Reg = LTRIM(RTRIM(bq.CommentAsXml.value('(root/item[@type="Reg"])[1]', 'VARCHAR(11)'))),
    Inv = LTRIM(RTRIM(bq.CommentAsXml.value('(root/item[@type="Inv"])[1]', 'VARCHAR(11)'))),
    Cus = LTRIM(RTRIM(bq.CommentAsXml.value('(root/item[@type="Cus"])[1]', 'VARCHAR(11)'))),
    Br  = LTRIM(RTRIM(bq.CommentAsXml.value('(root/item[@type="Br"])[1]', 'VARCHAR(11)'))) 
FROM    
    BaseQuery bq
)
SELECT ... t1.Col1 ... x.Col2 ...
FROM Table1 t1 
OUTER/CROSS APPLY (
    SELECT ...
    FROM Query q 
    WHERE ... join condition ... -- Query represents the second CTE
) x
ORDER BY ...

[ 3 ] Another solution is to insert those rows (extracted from Comment column) into a temp table (#Results) and then JOIN temp (#Results) table with another table (Table1):

;WITH BaseQuery AS 
(
    SELECT  
        Id, Name, Comment, 
        CONVERT(XML, '<root><item>' 
                + REPLACE(
                    REPLACE(
                        REPLACE(
                            REPLACE((SELECT Comment AS '*' FOR XML PATH('')), 
                            'Reg:', 
                            '</item><item type="Reg">'), 
                        'Inv:', 
                        '</item><item type="Inv">'), 
                    'Cus:', 
                    '</item><item type="Cus">'), 
                'Br:', 
                '</item><item type="Br">') + '</item></root>') CommentAsXml
    FROM    
        GenTransaction
)
SELECT  
    Id, Name, Comment, 
    Reg = LTRIM(RTRIM(bq.CommentAsXml.value('(root/item[@type="Reg"])[1]', 'VARCHAR(11)'))),
    Inv = LTRIM(RTRIM(bq.CommentAsXml.value('(root/item[@type="Inv"])[1]', 'VARCHAR(11)'))),
    Cus = LTRIM(RTRIM(bq.CommentAsXml.value('(root/item[@type="Cus"])[1]', 'VARCHAR(11)'))),
    Br  = LTRIM(RTRIM(bq.CommentAsXml.value('(root/item[@type="Br"])[1]', 'VARCHAR(11)'))) 
INTO #Results
FROM    
    BaseQuery bq; -- ORDER BY here should be used within final query

SELECT ...
FROM Table1 t1 INNER/LEFT OUTER/... JOIN #Results r ON ... join condition build using t1./r... ...
ORDER BY ...


Id, Name, Comment



回答2:


From documentation of WITH common_table_expression (Transact-SQL)

Specifies a temporary named result set, known as a common table expression (CTE). This is derived from a simple query and defined within the execution scope of a single SELECT, INSERT, UPDATE, or DELETE statement.

Because CTE result scoped for only one statement you need to save result of SELECT query in table variable or create another CTE

With table variable

DECLARE @BaseData AS TABLE (
    Id INT,
    Name VARCHAR(50),
    Comment VARCHAR(500),
    Reg VARCHAR(11),
    Inv VARCHAR(11),
    Cus VARCHAR(11),
    Br VARCHAR(11)
)

;WITH BaseQuery AS 
(
    -- your CTE
)

INSERT INTO @BaseData 
SELECT Id, Name, Comment, 
    Reg = LTRIM(RTRIM(bq.CommentAsXml.value('(root/item[@type="Reg"])[1]','VARCHAR(11)'))),
    Inv = LTRIM(RTRIM(bq.CommentAsXml.value('(root/item[@type="Inv"])[1]','VARCHAR(11)'))),
    Cus = LTRIM(RTRIM(bq.CommentAsXml.value('(root/item[@type="Cus"])[1]','VARCHAR(11)'))),
    Br  = LTRIM(RTRIM(bq.CommentAsXml.value('(root/item[@type="Br"])[1]','VARCHAR(11)'))) 
FROM BaseQuery
ORDER BY Id, Name, Comment

-- Join it with another table
SELECT *
FROM AnotherTable at
INNER JOIN @BaseData bd ON bd.Id = at.SomeId

WITH another CTE

;WITH BaseQuery AS 
(
    -- your CTE
)
,
BaseResult AS 
(
    SELECT Id, Name, Comment, 
    Reg = LTRIM(RTRIM(bq.CommentAsXml.value('(root/item[@type="Reg"])[1]','VARCHAR(11)'))),
    Inv = LTRIM(RTRIM(bq.CommentAsXml.value('(root/item[@type="Inv"])[1]','VARCHAR(11)'))),
    Cus = LTRIM(RTRIM(bq.CommentAsXml.value('(root/item[@type="Cus"])[1]','VARCHAR(11)'))),
    Br  = LTRIM(RTRIM(bq.CommentAsXml.value('(root/item[@type="Br"])[1]','VARCHAR(11)'))) 
    FROM BaseQuery
)

-- Join  second result with another table
SELECT *
FROM AnotherTable at
INNER JOIN BaseResult br ON br.Id = at.SomeId


来源:https://stackoverflow.com/questions/45450874/how-to-join-cte-query-with-another-table-in-sql-server-2008

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!