有条件的联接SQL表(将1:Many Join转换为1:1)

时间:2018-11-07 09:35:33

标签: sql sql-server

不确定如何用词表达我的问题/标题,因此,如果有人对我所追求的目标有最佳建议,将不胜感激!

总结:

我有下表

[Items] [I]
Id Date  Name 
1  07/11 Ball
2  07/11 Bat

[Prices] [P]
Id Date  Name Price
1  05/11 Ball 10.50
2  05/11 Bat  21.00
3  06/11 Ball 10.75
4  06/11 Bat  22.00
5  07/11 Ball 10.25
6  07/11 Bat  20.25

我想创建一个链接两个表的脚本,但只提取最新价格(id随日期增加而增加)

所以我希望我的结果是:

Id Name Price 
1  Ball 10.25
2  Bat  20.25

如果我进行简单的加入:

SELECT * FROM [ITEMS] [I]
LEFT JOIN [PRICES] [P] On [I].[NAME] = [P].[NAME]
WHERE [I].[DATE] = '2018-11-07'

然后,我最终每天有6行有价。我显然可以对其进行更改,并在末尾添加[P]。[DATE] ='2018-11-07',以便对其进行定价,但我希望它选择最新日期(以防万一该商品没有日期)收到一天的价格,我可以使用前一天的价格

我找到了以下代码:

SELECT * FROM [ITEMS] [I]
LEFT JOIN [PRICES] [P] On [I].[NAME] = [P].[NAME]
WHERE [I].[DATE] = '2018-11-07' 
AND [P].[ID] = 
(SELECT max([ID]) FROM [PRICES] WHERE [NAME] = 'Ball')

哪一个效果很好,但仅适用于WHERE [NAME] ='...'的项目,这似乎是可行的方法,但我不认为如何更改代码才能做到我所有的物品。

感谢您的帮助!

3 个答案:

答案 0 :(得分:2)

您可以使用TOP WITH Ties

 SELECT TOP 1 WITH TIES * 
 FROM [ITEMS] [I]
 LEFT JOIN [PRICES] [P] On [I].[NAME] = [P].[NAME]
 ORDER BY ROW_NUMBER() OVER (PARTITION BY I.NAME ORDER BY [I].[DATE] DESC)

答案 1 :(得分:1)

您可以使用TOP WITH TIES,但不需要窗口功能:

SELECT TOP (1) WITH TIES *
FROM [ITEMS] [I] LEFT JOIN
     [PRICES] [P] 
     ON [I].[NAME] = [P].[NAME]
ORDER BY [I].[DATE] DESC;

答案 2 :(得分:0)

另一种选择(2012版或更高版本)是使用First_value窗口功能:

SELECT DISTINCT 
        I.Id, 
        I.[Name], 
        FIRST_VALUE(P.Price) OVER(PARTITION BY I.[Name] ORDER BY P.[Date])
FROM Items As I
LEFT JOIN Prices As P
    ON I.[Name] = P.[Name]