我试图通过连接两个SQL表来创建一个SQL视图,并且只返回第二个表中的最低值和第一个表中与左连接类似的所有行。
我的问题可以通过下面的例子清楚地解释。
表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
在上面的数据中,我希望在两个表中的Table1
列相等时加入Table2
和Product,Grade and Term
,并在加入时返回Table1
的所有行从TradeValue
到匹配的第一条记录的Table2
列的最低值,并为结果视图的其他行创建TradeValue as NULL
,生成的视图应该包含Id
Table2
作为LTID
因此生成的SQL视图应为
RESULT
Id Product Grade Term Bid Offer TradeValue LTID
100 ABC A Q1 10 20 95 2
101 ABC A Q1 5 25 NULL 2
102 XYZ A Q2 25 30 NULL NULL
103 XYZ B Q2 20 30 100 3
我尝试使用以下查询
CREATE VIEW [dbo].[ViewCC]
AS
SELECT
a.Id,a.Product,a.Grade,a.Term,a.Bid,a.Offer,
b.TradeValue
FROM Table1 AS a
left JOIN (SELECT Product,Grade,Term,MIN(TradeValue) TradeValue from Table2 Group by Product,Grade,Term,) AS b
ON b.Product=a.Product
and b.Grade=a.Grade
and b.Term=a.Term
GO
上面的Query返回了以下数据,这些数据很容易出现在我写的查询中,但这不是我想要获取的数据
Id Product Grade Term Bid Offer TradeValue
100 ABC A Q1 10 20 95
101 ABC A Q1 5 25 95 --This should be null
102 XYZ A Q2 25 30 NULL
103 XYZ B Q2 20 30 100
我们可以看到TradeValue
的最小值被分配给Table1
中的所有匹配行,而且我无法从Table2返回Id As LTID
,因为我遇到{{1}的问题我不能用 b.Id 对它进行分组,因为它会返回太多行。
我可以知道更好的解决方法吗?
答案 0 :(得分:1)
您需要在Table1
的每条记录附加一个行号,这样才能满足只加入Table1
每组的第一条记录的要求:
CREATE VIEW [dbo].[ViewCC]
AS
SELECT a.Id, a.Product, a.Grade, a.Term, a.Bid, a.Offer,
b.TradeValue, b.Id AS LTID
FROM (
SELECT *, ROW_NUMBER() OVER(PARTITION BY Product, Grade, Term ORDER BY Id) AS rn
FROM Table1
) a
OUTER APPLY (
SELECT TOP 1 CASE WHEN rn = 1 THEN TradeValue
ELSE NULL
END AS TradeValue, Id
FROM Table2
WHERE Product=a.Product AND Grade=a.Grade AND Term=a.Term
ORDER BY TradeValue) b
GO
OUTER APPLY
返回一个表格表达式,其中包含Table2
与TradeValue
最低的匹配记录,如果不存在匹配记录,则为NULL
。