SQL Server 2005:如何只连接一次表行
我想我已经看到了MySQL类似问题的答案,但我正在努力找到一个适用于SQLServer2005的答案 我有一张这样的桌子:SQL Server 2005:如何只连接一次表行,sql,sql-server,sql-server-2005,Sql,Sql Server,Sql Server 2005,我想我已经看到了MySQL类似问题的答案,但我正在努力找到一个适用于SQLServer2005的答案 我有一张这样的桌子: | ID | RelationalID | Year ---------------------------- | 1 | A | 2014 | 2 | A | 2014 | 3 | B | 2014 | 4 | A | 2015 | 5 | B | 20
| ID | RelationalID | Year
----------------------------
| 1 | A | 2014
| 2 | A | 2014
| 3 | B | 2014
| 4 | A | 2015
| 5 | B | 2015
当我加入同一个表,其中RelationID匹配,但年份不同时,我希望得到这样的结果:
| 2014_ID | 2015_ID | RelationalID |
------------------------------------
| 1 | 4 | A |
| 2 | NULL | A |
| 3 | 5 | B |
但标准联接最终会得到重复的匹配:
| 2014_ID | 2015_ID | RelationalID |
------------------------------------
| 1 | 4 | A |
| 2 | 4 | A |
| 3 | 5 | B |
在SQL Server 2005中,如果右表中的匹配项只联接一次,是否有方法联接两个表
我尝试了此查询,但未成功:
SELECT * FROM myTable
LEFT JOIN (SELECT * FROM myTable) AS t ON t.RelationalID = myTable.RelationalID
WHERE myTable.Year = 2014 and t.Year = 2015
可能有几种方法可以解决这个问题,但下面展示了在查询中使用派生表的示例
SELECT
q1.Id AS [2014_Id],
q2.Id AS [2015_Id],
q1.RelationalId
FROM (SELECT
MAX(a.Id) AS Id,
a.RelationalId
FROM [table] a
WHERE a.Year = 2014
GROUP BY
a.RelationalId) q1
INNER JOIN (SELECT
MAX(b.Id) AS Id,
b.RelationalId
FROM [table] b
WHERE b.Year = 2015
GROUP BY
b.RelationalId) q2
ON q2.RelationalId = q1.RelationalId
可能有几种方法可以解决这个问题,但下面展示了在查询中使用派生表的示例
SELECT
q1.Id AS [2014_Id],
q2.Id AS [2015_Id],
q1.RelationalId
FROM (SELECT
MAX(a.Id) AS Id,
a.RelationalId
FROM [table] a
WHERE a.Year = 2014
GROUP BY
a.RelationalId) q1
INNER JOIN (SELECT
MAX(b.Id) AS Id,
b.RelationalId
FROM [table] b
WHERE b.Year = 2015
GROUP BY
b.RelationalId) q2
ON q2.RelationalId = q1.RelationalId
下面的Sql将给出您想要的结果,但正如我前面所说的,复杂性将取决于表中的原始数据集。这是SQL小提琴--祝你好运
;WITH CTE_Union AS
(SELECT
a.Id AS Id2014,
NULL AS Id2015,
a.RelationalId
FROM [YourTable] a
WHERE a.Year = 2014
UNION
SELECT
NULL AS Id2014,
b.Id AS Id2015,
b.RelationalId
FROM [YourTable] b
WHERE b.Year = 2015)
SELECT Distinct CASE WHEN Id2014 IS NULL THEN (SELECT MIN(Id2014) FROM CTE_Union C WHERE C.RelationalId =M.RelationalId) ELSE Id2014 END AS ID2014 ,
CASE WHEN Id2015 IS NULL AND Id2014 = (SELECT MIN(Id2014) FROM CTE_Union C2 WHERE C2.RelationalId =M.RelationalId) THEN (SELECT MIN(Id2015) FROM CTE_Union C WHERE C.RelationalId =M.RelationalId) ELSE Id2015 END
,RelationalID
FROM CTE_Union M
下面的Sql将给出您想要的结果,但正如我前面所说的,复杂性将取决于表中的原始数据集。这是SQL小提琴--祝你好运
;WITH CTE_Union AS
(SELECT
a.Id AS Id2014,
NULL AS Id2015,
a.RelationalId
FROM [YourTable] a
WHERE a.Year = 2014
UNION
SELECT
NULL AS Id2014,
b.Id AS Id2015,
b.RelationalId
FROM [YourTable] b
WHERE b.Year = 2015)
SELECT Distinct CASE WHEN Id2014 IS NULL THEN (SELECT MIN(Id2014) FROM CTE_Union C WHERE C.RelationalId =M.RelationalId) ELSE Id2014 END AS ID2014 ,
CASE WHEN Id2015 IS NULL AND Id2014 = (SELECT MIN(Id2014) FROM CTE_Union C2 WHERE C2.RelationalId =M.RelationalId) THEN (SELECT MIN(Id2015) FROM CTE_Union C WHERE C.RelationalId =M.RelationalId) ELSE Id2015 END
,RelationalID
FROM CTE_Union M
你可以根据行号得到结果,但是你需要一个如何分配它们的规则,我假设它是基于Id的
;WITH cte AS
(SELECT Id,
RelationalId,
year,
row_number()
over (partition by RelationalId, year
order by Id) as rn
FROM [YourTable]
)
select t1.id as Id_2014,t2.id as Id_2015, t1.RelationalId
from cte as t1 left join cte as t2
on t1.RelationalId = t2.RelationalId
and t1.rn = t2.rn
and t2.year = 2015
where t1.Year = 2014
这是基于TMNT2014的您可以根据行数获得结果,但您需要一个如何分配它们的规则,我假设它是基于Id的
;WITH cte AS
(SELECT Id,
RelationalId,
year,
row_number()
over (partition by RelationalId, year
order by Id) as rn
FROM [YourTable]
)
select t1.id as Id_2014,t2.id as Id_2015, t1.RelationalId
from cte as t1 left join cte as t2
on t1.RelationalId = t2.RelationalId
and t1.rn = t2.rn
and t2.year = 2015
where t1.Year = 2014
这是基于TMNT2014的
我使用一个并集,然后根据关系id对每一方进行排序,然后左键加入它们。
以下是输出:
Id2014 Id2015 RelationalID
1 4 A
2 NULL A
3 5 B
我使用一个并集,然后根据关系id对每一方进行排序,然后左键加入它们。
以下是输出:
Id2014 Id2015 RelationalID
1 4 A
2 NULL A
3 5 B
您可以添加不起作用的查询吗?示例非工作查询是:SELECT*FROM myTable LEFT JOIN SELECT*FROM myTable AS t ON t.RelationalID=myTable.RelationalID其中myTable.Year=2014和t.Year=2015您可以解释为什么{2,4,A}不是有效的输出,而是{1,4,A}是吗?基本上这是不可能的,除非你想进行一个非常复杂的查询。因此,下一个问题是,为什么要以希望看到的形式显示数据?@Anon{2,4,A}无效,因为集合{1,4,A}中已经匹配了2015_ID 4您可以添加不起作用的查询吗?示例非工作查询是:SELECT*FROM myTable LEFT JOIN SELECT*FROM myTable AS t ON t.RelationalID=myTable.RelationalID其中myTable.Year=2014和t.Year=2015您可以解释为什么{2,4,A}不是有效的输出,而是{1,4,A}是吗?基本上这是不可能的,除非你想进行一个非常复杂的查询。因此,下一个问题是,为什么您希望数据以您希望看到的形式出现?@Anon{2,4,A}无效,因为集合{1,4,A}中已经匹配了2015_ID 4。这不起作用-即使得到不同的行,它仍然可以多次匹配右表中的同一行。那么在这种情况下,您想要哪个ID。第一个还是最后一个?或者中间有3个?“这有关系吗?”斯邦格斯库修改了答案。也许这就是你要寻找的东西——它仍然可以多次匹配右表中的同一行,即使它得到的是不同的行。那么在这种情况下,你想要哪个Id呢。第一个还是最后一个?或者中间有3个?“这有关系吗?”斯邦格斯库修改了答案。也许这就是您所寻找的CTE方法与分区的关系。这个方法得到的结果比@Kevin Cook的答案多一些,所以我把它标记为已接受的答案。我不熟悉分区,所以这非常有用。谢谢大家的帮助。CTE分区方法似乎可以解决这个问题。这个方法得到的结果比@Kevin Cook的答案多一些,所以我把它标记为已接受的答案。我不熟悉分区,所以这非常有用。谢谢大家的帮助。