根据几列的相等性连接两个 SQL 表
Joining two SQL tables based on the equality of few columns
我正在尝试通过加入两个 SQL table 和 return 来创建一个 SQL 视图,只有第二个 table 和所有的最低值第一个 table 的行类似于左连接。
我的问题可以用下面的例子清楚地解释。
表 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
,只要 table 的列 Product,Grade and Term
相等且 return Table1
中的所有行,同时将 Table2
中列 TradeValue
的最低值连接到匹配的第一条记录,并为结果视图的其他行制作 TradeValue as NULL
和结果视图应具有 Table2
的 Id
作为 LTID
所以结果 SQL 视图应该是
结果
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
上面的查询return编辑了以下适合我写的查询的数据,但这不是我想要得到的
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
中的所有匹配行,而且我无法从表 2 return Id As LTID
,因为我group by
子句有问题,因为我无法按 b.Id 对它进行分组,因为它 return 行太多。
我可以知道更好的处理方法吗?
您需要为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
returns 一个 table 表达式,包含 Table2
中具有最低 TradeValue
的匹配记录,或者 NULL
如果没有存在匹配记录。
我正在尝试通过加入两个 SQL table 和 return 来创建一个 SQL 视图,只有第二个 table 和所有的最低值第一个 table 的行类似于左连接。
我的问题可以用下面的例子清楚地解释。
表 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
,只要 table 的列 Product,Grade and Term
相等且 return Table1
中的所有行,同时将 Table2
中列 TradeValue
的最低值连接到匹配的第一条记录,并为结果视图的其他行制作 TradeValue as NULL
和结果视图应具有 Table2
的 Id
作为 LTID
所以结果 SQL 视图应该是
结果
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
上面的查询return编辑了以下适合我写的查询的数据,但这不是我想要得到的
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
中的所有匹配行,而且我无法从表 2 return Id As LTID
,因为我group by
子句有问题,因为我无法按 b.Id 对它进行分组,因为它 return 行太多。
我可以知道更好的处理方法吗?
您需要为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
returns 一个 table 表达式,包含 Table2
中具有最低 TradeValue
的匹配记录,或者 NULL
如果没有存在匹配记录。