通过脚本将不相关的列添加到组

时间:2012-02-23 06:56:30

标签: sql sql-server-2008 tsql

这是我的示例表和值:

CREATE TABLE [dbo].[Test]
(
[Id]     BIGINT  NOT NULL  DEFAULT(0),
[VId]    BIGINT  NOT NULL  DEFAULT(0),
[Level]  INT     NOT NULL  DEFAULT(0)
);

INSERT INTO [dbo].[Test] ([Id], [VId], [Level]) VALUES (100, 1, 1);
INSERT INTO [dbo].[Test] ([Id], [VId], [Level]) VALUES (101, 1, 2);
INSERT INTO [dbo].[Test] ([Id], [VId], [Level]) VALUES (102, 1, 3);
INSERT INTO [dbo].[Test] ([Id], [VId], [Level]) VALUES (103, 2, 1);
INSERT INTO [dbo].[Test] ([Id], [VId], [Level]) VALUES (104, 3, 1);
INSERT INTO [dbo].[Test] ([Id], [VId], [Level]) VALUES (105, 3, 2);
INSERT INTO [dbo].[Test] ([Id], [VId], [Level]) VALUES (106, 4, 1);
INSERT INTO [dbo].[Test] ([Id], [VId], [Level]) VALUES (107, 4, 2);
INSERT INTO [dbo].[Test] ([Id], [VId], [Level]) VALUES (108, 4, 3);
INSERT INTO [dbo].[Test] ([Id], [VId], [Level]) VALUES (109, 4, 4);

所以现在我使用这个脚本:

SELECT 
    [T].[VId], MAX ([T].[Level]) AS [MaxLevel]
FROM 
    [dbo].[Test] AS [T]
GROUP BY 
    [T].[VId];

它返回:

VId    MaxLevel
1      3
2      1
3      2
4      4

但我也需要Id列,我无法将其添加到Group by脚本,我需要以下值:

VId    MaxLevel   Id
1      3          102
2      1          103
3      2          105
4      4          109

你的建议是什么?

此外,以下值足够任何VId中的Id与最大(级别)

Id
102
103
105
109

4 个答案:

答案 0 :(得分:4)

2008年接受这个问题,因为那是你正在使用的:

declare @Test table
(
[Id]            BIGINT      NOT NULL    DEFAULT(0),
[VId]           BIGINT      NOT NULL    DEFAULT(0),
[Level]         INT         NOT NULL    DEFAULT(0)
);

INSERT INTO @Test ([Id], [VId], [Level])
VALUES (100, 1, 1),(101, 1, 2),(102, 1, 3),(103, 2, 1),(104, 3, 1),
(105, 3, 2),(106, 4, 1),(107, 4, 2),(108, 4, 3),(109, 4, 4);

;With Numbered as (
    select *,
        RANK() OVER (PARTITION BY VId ORDER BY [Level] desc) as rn
from @Test)
select VId,Level,Id from Numbered where rn=1

请注意(与其他解决方案一样)如果有两行具有相同的最大级别,则每VId输出多行。如果您不想这样做,请将RANK()切换为ROW_NUMBER()并且任意一个将获胜 - 或者如果您想要一个特定的赢家,请将该条件添加到{{1}窗口函数。

答案 1 :(得分:2)

使用VId列连接相同的表

类似的东西:

SELECT [T].[VId], [T].[MaxLevel], [T1].[Id]
FROM [dbo].[Test] AS [T1] JOIN
  (SELECT [T].[VId], MAX ([T].[Level]) AS [MaxLevel]
    FROM [dbo].[Test] AS [T]
    GROUP BY [T].[VId]) AS [T] 
ON [T1].[VId] = [T].[VId]
AND [T1].[Level] = [T].[MaxLevel]
ORDER BY [T].[VId];

结果将是:

VId MaxLevel  Id
1   3         102
2   1         103
3   2         105
4   4         109

答案 2 :(得分:1)

使用此:

WITH LastLevels AS
(
SELECT 
    [T].[VId] AS [VID], 
    MAX ([T].[Level]) AS [MaxLevel]

FROM [dbo].[Test] AS [T]
GROUP BY [T].[VId]
)

SELECT [LastLevels].[VID],[LastLevels].[MaxLevel], [Te].[Id]
FROM [dbo].[Test] AS [Te]
INNER JOIN [LastLevels]
ON [LastLevels].[VID]=[Te].[VId]
AND [LastLevels].[MaxLevel]=[Te].[Level]
ORDER BY [LastLevels].[VID];

答案 3 :(得分:0)

SELECT ID, [VId], [MaxLevel] From
(
    SELECT 
        [T].[VId], MAX ([T].[Level]) AS [MaxLevel]
    FROM 
        [dbo].[Test] AS [T]
    GROUP BY 
        [T].[VId]
)K
INNER JOIN [Test] T on T.[VId] = K.[VId] and T.[Level] = K.MaxLevel