我试图通过连接两个SQL表来创建一个SQL视图并返回第二个表中的最新值,并且第一个表中的所有行类似于左连接以及来自table2的TOP 1记录,其中表中没有匹配1按产品,等级,术语分组
我的问题可以通过下面的例子清楚地解释。
表1
Id Product Grade Term Bid Offer
100 ABC A Q1 10 20
101 ABC A Q1 5 25
102 XYZ A Q2 25 30
103 XYZ B Q2 20 30
表2
Id Product Grade Term TradeValue
1 ABC A Q1 100
2 ABC A Q1 95
3 XYZ B Q2 100
4 PQR C Q2 100
5 PQR C Q2 200
在上面的数据中,我希望在两个表中的Table1
列相等时加入Table2
和Product,Grade and Term
,并在加入时返回Table1
的所有行从TradeValue
到匹配的第一条记录的Table2
列的最新值,并为结果视图的其他行创建TradeValue as NULL
,生成的视图应该包含Id
Table2
作为LTID
并且它还应返回表2中的前1行,其中产品,等级和期限不等于按产品,等级和期限分组
因此生成的SQL视图应为
RESULT
Id Product Grade Term Bid Offer TradeValue LTID
100 ABC A Q1 10 20 100 2
101 ABC A Q1 5 25 NULL NULL
102 XYZ A Q2 25 30 NULL NULL
103 XYZ B Q2 20 30 100 3
104 PQR C Q2 NULL NULL 200 5
我尝试使用以下查询
http://sqlfiddle.com/#!3/e8884/7
我们可以看到TradeValue
的最新值被分配给Table1
中的所有匹配行,而且我也无法返回Table2中未找到匹配项的TOP 1行
我可以知道更好的解决方法吗?
答案 0 :(得分:1)
试试这个:
SELECT ROW_NUMBER() OVER(ORDER BY d.Product) as ID,d.*,t1.Bid,t1.Offer,t2.LastTradeValue,t2.ID AS LTID
FROM
(
SELECT Product,Grade,Term
FROM Table1
UNION
SELECT Product,Grade,Term
FROM Table2
) d
LEFT JOIN Table1 t1 ON d.Product=t1.Product AND d.Grade=t1.Grade AND d.Term=t1.Term
OUTER APPLY
(
SELECT TOP 1 * FROM Table2 t2 WHERE d.Product=t2.Product AND d.Grade=t2.Grade AND d.Term=t2.Term
ORDER BY t2.ID DESC
) t2
答案 1 :(得分:0)
由于您使用的是Sql Server 2012,请让我建议以下内容:
DECLARE @t1 TABLE
(
Id INT ,
Product CHAR(3) ,
Grade CHAR(1) ,
Term CHAR(2) ,
Bid INT ,
Offer INT
)
DECLARE @t2 TABLE
(
Id INT ,
Product CHAR(3) ,
Grade CHAR(1) ,
Term CHAR(2) ,
TradeValue INT
)
INSERT INTO @t1
VALUES ( 100, 'ABC', 'A', 'Q1', 10, 20 ),
( 101, 'ABC', 'A', 'Q1', 5, 25 ),
( 102, 'XYZ', 'A', 'Q2', 25, 30 ),
( 103, 'XYZ', 'B', 'Q2', 20, 30 )
INSERT INTO @t2
VALUES ( 1, 'ABC', 'A', 'Q1', 100 ),
( 2, 'ABC', 'A', 'Q1', 95 ),
( 3, 'XYZ', 'B', 'Q2', 100 ),
( 4, 'PQR', 'C', 'Q2', 100 ),
( 5, 'PQR', 'C', 'Q2', 200 ),
( 6, 'TTT', 'C', 'Q2', 200 ),
( 7, 'TTT', 'C', 'Q2', 201 ),
( 8, 'JJJ', 'C', 'Q2', 500 );
WITH cte
AS ( SELECT t1.Id AS t1Id ,
t1.Product AS t1Product ,
t1.Grade AS t1Grade ,
t1.Term AS t1Term ,
t1.Bid AS t1Bid ,
t1.Offer AS t1Offer ,
IIF(t1.ID IS NULL, t1.Id, t2.Id) AS ordert2Id ,
t2.Id AS t2Id ,
t2.Product AS t2Product ,
t2.Grade AS t2Grade ,
t2.Term AS t2Term ,
t2.TradeValue AS t2TradeValue
FROM @t2 t2
FULL JOIN @t1 t1 ON t2.Product = t1.Product
AND t2.Grade = t1.Grade
AND t2.Term = t1.Term
),
cte2
AS ( SELECT * ,
ROW_NUMBER() OVER ( PARTITION BY t2Product, t2Grade, t2Term, t1Id ORDER BY ordert2Id ) AS rn1 ,
RANK() OVER ( PARTITION BY t2Product, t2Grade, t2Term ORDER BY t1Id ) AS rn2 ,
LAST_VALUE(t2TradeValue) OVER ( PARTITION BY t2Product, t2Grade, t2Term ORDER BY ordert2Id ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) AS TradeValue ,
LAST_VALUE(t2Id) OVER ( PARTITION BY t2Product, t2Grade, t2Term ORDER BY t2Id ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) AS TradeId
FROM cte
)
SELECT t1Id AS ID ,
ISNULL(t1Product, t2Product) AS Product ,
ISNULL(t1Grade, t2Grade) AS Product ,
ISNULL(t1Term, t2Term) AS Product ,
t1Bid AS Bid ,
t1Offer AS Offer,
IIF(rn2 = 1, TradeValue, NULL) AS TradeValue,
IIF(rn2 = 1, TradeId, NULL) AS LTID
FROM cte2
WHERE rn1 = 1
输出:
ID Product Product Product Bid Offer TradeValue LTID
NULL PQR C Q2 NULL NULL 200 5
100 ABC A Q1 10 20 95 2
101 ABC A Q1 5 25 NULL NULL
102 XYZ A Q2 25 30 NULL NULL
103 XYZ B Q2 20 30 100 3