如何使用CTE为多个输入重复查询?

时间:2017-05-24 18:35:15

标签: sql-server

我有以下查询:

SELECT **top 1** account, date, result
FROM table_1 as t1
JOIN table_2 at t2 ON t1.accountId = t2.frn_accountId
WHERE accountID = 1
ORDER BY date

此查询返回我想要的结果,但是我想要多个accountID的结果。他们的查询应返回每个accountID的前1个值。

生成accountID-s列表的查询是:

SELECT accountID from lskin WHERE refname LIKE '%BHA%' and isactive = 1

如何编写此查询以便生成所需的结果?我一直在玩CTE但是还没有能够做到正确。它不一定与CTE有关,我只是觉得使用CTE会更容易......

3 个答案:

答案 0 :(得分:2)

这是CTE解决方案。

SELECT *
FROM (SELECT account
        , date
        , result
        , ROW_NUMBER() OVER (PARTITION BY t1.accountId ORDER BY date DESC) AS Rownum
    FROM table_1 AS t1
    INNER JOIN table_2 AS t2 
        ON t1.accountId = t2.frn_accountId
    INNER JOIN lskin AS l 
        ON l.accountID = t1.accountID 
    WHERE l.refname LIKE '%BHA%'
) a
WHERE a.Rownum = 1;

答案 1 :(得分:0)

在帐户上使用日期和分组的最大值,或者适当的列。

SELECT 
    account, 
    DT = max(date), 
    result
FROM table_1 as t1
JOIN table_2 as t2 ON t1.accountId = t2.frn_accountId
JOIN lskin as l on l.accountID = t1.accountID 
WHERE l.refname like '%BHA%'
GROUP BY
    account
    ,result

如果分组不正确,只需加入子查询即可将其限制为最大日期。只需根据需要更改表名。

SELECT 
    account, 
    date, 
    result
FROM table_1 as t1
JOIN table_2 as t2 ON t1.accountId = t2.frn_accountId
JOIN lskin as l on l.accountID = t1.accountID 
INNER JOIN (select max(date) dt, accountID from table_1 group by accountID) tt on tt.dt = t1.accountId and tt.accountId = t1.accountId
WHERE l.refname like '%BHA%'

答案 2 :(得分:0)

忽略顶部的CTE。那只是测试数据。

/* CTE Test Data */
; WITH table_1 AS ( 
    SELECT 1 AS accountID, 'acc1' AS account UNION ALL
    SELECT 2 AS accountID, 'acc2' AS account UNION ALL
    SELECT 3 AS accountID, 'acc3' AS account
)
, table_2 AS (
    SELECT 1 AS frn_accountID, 'new1' AS result, GETDATE() AS [date] UNION ALL
    SELECT 1 AS frn_accountID, 'mid1' AS result, GETDATE()-1 AS [date] UNION ALL
    SELECT 1 AS frn_accountID, 'old1' AS result, GETDATE()-2 AS [date] UNION ALL
    SELECT 2 AS frn_accountID, 'new2' AS result, GETDATE() AS [date] UNION ALL
    SELECT 2 AS frn_accountID, 'mid2' AS result, GETDATE()-1 AS [date] UNION ALL
    SELECT 2 AS frn_accountID, 'old2' AS result, GETDATE()-2 AS [date] UNION ALL
    SELECT 3 AS frn_accountID, 'new3' AS result, GETDATE() AS [date] UNION ALL
    SELECT 3 AS frn_accountID, 'mid3' AS result, GETDATE()-1 AS [date] UNION ALL
    SELECT 3 AS frn_accountID, 'old3' AS result, GETDATE()-2 AS [date]

)
, lskin AS ( 
    SELECT 1 AS accountID, 'purple' AS refName, 1 AS isActive UNION ALL
    SELECT 2 AS accountID, 'blue' AS refName, 1 AS isActive UNION ALL
    SELECT 3 AS accountID, 'orange' AS refName, 0 AS isActive UNION ALL
    SELECT 4 AS accountID, 'blue' AS refName, 1 AS isActive
)
, 
/* Just use the below and remove comment markers around WITH to build Orders CTE. */
/* ; WITH */ 
theCTE AS (   
SELECT s1.accountID, s1.account, s1.result, s1.[date]
FROM (
    SELECT t1.accountid, t1.account, t2.result, t2.[date], ROW_NUMBER() OVER (PARTITION BY t1.account ORDER BY t2.[date]) AS rn
    FROM table_1 t1
    INNER JOIN table_2 t2 ON t1.accountID = t2.frn_accountID
) s1
WHERE s1.rn = 1  
)
SELECT lskin.accountID 
FROM lskin
INNER JOIN theCTE ON theCTE.accountid = lskin.accountID
WHERE lskin.refName LIKE '%blue%'
    AND lskin.isActive = 1
;

EDITED: 我仍然对你的数据结构做了很多假设。再次,确保你查询你需要的东西。 CTE非常棒,但您不希望意外地过滤掉预期的结果。