来自Top 1的SQL连接表

时间:2015-01-16 21:55:50

标签: sql sql-server join

我已经在StackOverflow上做了很多搜索,并且无法适应其他SQL加入我自己案例的“前1”答案,所以我希望其他人可以指出我错过的内容。

表A

UniqueTableID    TaskID     ReferenceID
1                Task_1     Group_1
2                Task_2     Group_2
3                Task_2     Group_3
4                Task_3     Group_4
5                Task_3     Group_5
6                Task_4     Group_6

表B

GroupID     GroupName
Group_1     Group_AAA
Group_2     Group_BBB
Group_3     Group_CCC
Group_4     Group_DDD
Group_5     Group_EEE
Group_6     Group_FFF

我想要的是为每个TaskID返回一个GroupName(TableA.ReferenceID = TableB.GroupID)。对于具有多个GroupName引用的TaskID,我不关心返回哪一个,所以我尝试使用TOP 1.

此查询(及其许多变体):

SELECT A.TaskID, B.GroupName
FROM [TableA] A
JOIN [TableB] B
ON B.GroupID = (
    SELECT TOP 1 [GroupID] 
    FROM [TableB] 
    WHERE [GroupID] = A.ReferenceID
)

给我这张桌子:

结果

TaskID      GroupName
Task_1      Group_AAA
Task_2      Group_BBB
Task_2      Group_CCC
Task_3      Group_DDD
Task_3      Group_EEE
Task_4      Group_FFF

我怎样才能得到这个:

通缉结果

TaskID      GroupName
Task_1      Group_AAA
Task_2      Group_BBB
Task_3      Group_DDD
Task_4      Group_FFF

感谢您的时间和帮助!

3 个答案:

答案 0 :(得分:2)

我认为最好的方法是使用行号。

虽然您可以在主表上进行分组(如Ron Smith的答案),但您必须按所有非GroupName列进行分组。使用行号加入表格,你不会。

以下是如何为您的数据执行此操作的示例:

SELECT A.TaskID, s.GroupName
FROM [TableA] A
JOIN (SELECT [GroupID],
             [GroupName],
             ROW_NUMBER() OVER (Partition By GroupID ORDER BY GroupName) AS RN
) as subselect s
ON A.ReferenceID = s.GroupID AND s.RN = 1

解释:

您正在使用行号为子查询中的每个项目指定唯一编号。您可以选择要分区的内容(在本例中为GroupID)以及要排序的内容(在本例中为GroupName)。因为您只选择RN = 1的项目,所以您将始终使用此查询获得最低的GroupName。但您可以根据需要更改订单。

正如我设置的那样,你会得到与你的例子相同的结果,但我认为很清楚如何改变它。

答案 1 :(得分:0)

如果您希望每个任务按字母顺序排列第一个GroupName,则可以使用min

SELECT
    A.TaskID,
    min(B.GroupName) as GroupName
FROM [TableA] A
    JOIN [TableB] B
    ON B.GroupID = A.ReferenceID
GROUP BY A.TaskID

答案 2 :(得分:0)

使用此:

declare @data1 as table(UniqueTableID int primary key ,TaskID varchar(50),ReferenceID varchar(50))
insert into @data1 values (1,'Task_1','Group_1')
insert into @data1 values (2,'Task_2','Group_2')
insert into @data1 values (3,'Task_2','Group_3')
insert into @data1 values (4,'Task_3','Group_4')
insert into @data1 values (5,'Task_3','Group_5')
insert into @data1 values (6,'Task_4','Group_6')

declare @data2 as table(GroupID varchar(50),GroupName varchar(50))
insert into @data2 values ('Group_1','Group_AAA')
insert into @data2 values ('Group_2','Group_BBB')
insert into @data2 values ('Group_3','Group_CCC')
insert into @data2 values ('Group_4','Group_DDD')
insert into @data2 values ('Group_5','Group_EEE')
insert into @data2 values ('Group_6','Group_FFF')

SELECT B.TaskID,A.GroupName
FROM @data2 A INNER JOIN (select distinct TaskID,(select top 1 ReferenceID from @data1 d2 where d2.TaskID = d1.TaskID)as ReferenceID from @data1 d1) B
ON A.GroupID = B.ReferenceID