Sql server 仅从临时表中选择所有次高值

Sql server 仅从临时表中选择所有次高值,sql-server,tsql,sql-server-2008-r2,Sql Server,Tsql,Sql Server 2008 R2,使用T-SQL Server 2008 R2,我尝试只列出临时表中特定列中具有第二高值的行,然后将结果放入新的临时表中。PK是ID,它可以有越来越多的版本号,然后是唯一的代码 例如: ID | Name| Version | Code ------------------------ 1 | A | 1 | 10 1 | A | 2 | 20 1 | A | 3 | NULL 2 | B | 1 | 40 2

使用T-SQL Server 2008 R2,我尝试只列出临时表中特定列中具有第二高值的行,然后将结果放入新的临时表中。PK是ID,它可以有越来越多的版本号,然后是唯一的代码

例如:

 ID | Name| Version | Code
------------------------
 1  | A   | 1       | 10
 1  | A   | 2       | 20
 1  | A   | 3       | NULL
 2  | B   | 1       | 40
 2  | B   | 2       | 50
 2  | C   | 1       | 60
查询的预期结果是

ID |  Version | Code
------------------------
1  |  2       | 20
2  |  1       | 40
SELECT ID,Name,[Version],Code
FROM (
        SELECT ROW_NUMBER() OVER (PARTITION BY NAME ORDER BY [Version] DESC) AS RNK,*
        FROM
            (
                SELECT 1 ID, 'A' Name ,1 [Version] ,10 Code
                UNION ALL
                SELECT 1, 'A', 2 ,20
                UNION ALL
                SELECT 1, 'A', 3 ,30
                UNION ALL
                SELECT 1, 'A', 4 ,NULL
                UNION ALL
                SELECT 2, 'B', 1 ,40
                UNION ALL
                SELECT 2, 'B', 2 ,50
                UNION ALL
                SELECT 2, 'C', 1 ,60
            )B
        )BASE
WHERE RNK =2
为了实现这一点,我需要对下面的查询进行调整,以获取第二高的值,只要结果给出的版本号大于1。这些结果来自临时表,然后将被放入最终结果临时表中。编辑:请注意,这将应用于33000行数据,所以我更喜欢整洁的东西,而不是插入值。谢谢

当前查询:

SELECT
    ID
    ,Version
    ,Code
INTO 
    #table2
FROM
    #table1

SELECT * 
FROM #table2
WHERE Version > 1
ORDER BY ID asc

DROP TABLE #table1
DROP TABLE #table2
我曾尝试运行where子句where Version<从表2中选择MAXVERSION,但这没有效果,可能是由于唯一的代码值,并且在任何情况下,在我有3个以上版本的情况下都不起作用

我们将感激地接受这些想法


提前感谢。

如果主键仅为ID,则有重复的行。所以我假设您的主键是其他的东西,例如ID、版本、名称。您有两行具有相同ID和相同版本,您希望对此应用什么样的规则?最低数目

我举了一个你想要的例子:

首先声明必要的表:

declare @table1 table (
    Id int,
    Name nvarchar(20),
    [Version] int,
    Code int
)

insert into @table1 values (1,'A',1,10),(1,'A',2,20),(1,'A',3,30),(1,'A',4,NULL)
                          ,(2,'B',1,40),(2,'B',2,50),(2,'C',1,60);
然后执行查询以获取结果:

with HighestVersions (Id, MaxVersion) As 
(
    select Id, max(version) from @table1 group by Id
)
select
    t1.Id,
    t1.[Version],
    min(t1.Code) as Code
from
    @table1 t1
    inner join
        HighestVersions hv
        on
            hv.Id = t1.Id
            and (hv.MaxVersion-1) = t1.[Version]
group by
    t1.Id
    ,t1.[Version]
我不得不用最外层的select做一些肮脏的把戏,这是因为重复的“Id”和“Version”。否则您将得到两行ID=2,版本=1

如果要删除空值,可以根据上次编辑更改WITH part:

with HighestVersions (Id, MaxVersion) As 
(
    select Id, max(version) from @table1 where Code is not null group by Id
)

如果主键仅为ID,则有重复的行。所以我假设您的主键是其他的东西,例如ID、版本、名称。您有两行具有相同ID和相同版本,您希望对此应用什么样的规则?最低数目

我举了一个你想要的例子:

首先声明必要的表:

declare @table1 table (
    Id int,
    Name nvarchar(20),
    [Version] int,
    Code int
)

insert into @table1 values (1,'A',1,10),(1,'A',2,20),(1,'A',3,30),(1,'A',4,NULL)
                          ,(2,'B',1,40),(2,'B',2,50),(2,'C',1,60);
然后执行查询以获取结果:

with HighestVersions (Id, MaxVersion) As 
(
    select Id, max(version) from @table1 group by Id
)
select
    t1.Id,
    t1.[Version],
    min(t1.Code) as Code
from
    @table1 t1
    inner join
        HighestVersions hv
        on
            hv.Id = t1.Id
            and (hv.MaxVersion-1) = t1.[Version]
group by
    t1.Id
    ,t1.[Version]
我不得不用最外层的select做一些肮脏的把戏,这是因为重复的“Id”和“Version”。否则您将得到两行ID=2,版本=1

如果要删除空值,可以根据上次编辑更改WITH part:

with HighestVersions (Id, MaxVersion) As 
(
    select Id, max(version) from @table1 where Code is not null group by Id
)
试试这个:

DECLARE @List TABLE (ID int, Name char(1), Version int, Code int NULL)

INSERT INTO @List
VALUES
(1, 'A', 1, 10),
(1, 'A', 2, 20),
(1, 'A', 3, 30),
(1, 'A', 4, NULL),
(2, 'B', 1, 40),
(2, 'B', 2, 50),
(2, 'C', 1, 60)


SELECT
    ID, Name, Version, Code
FROM
   (
    SELECT
        *,
       ROW_NUMBER() OVER (PARTITION BY ID, Name ORDER BY Version DESC) Rn
    FROM @List
   ) a
WHERE
    a.Rn = 2
试试这个:

DECLARE @List TABLE (ID int, Name char(1), Version int, Code int NULL)

INSERT INTO @List
VALUES
(1, 'A', 1, 10),
(1, 'A', 2, 20),
(1, 'A', 3, 30),
(1, 'A', 4, NULL),
(2, 'B', 1, 40),
(2, 'B', 2, 50),
(2, 'C', 1, 60)


SELECT
    ID, Name, Version, Code
FROM
   (
    SELECT
        *,
       ROW_NUMBER() OVER (PARTITION BY ID, Name ORDER BY Version DESC) Rn
    FROM @List
   ) a
WHERE
    a.Rn = 2

我已经测试了下面的代码,它根据您期望的查询结果给出了输出

ID |  Version | Code
------------------------
1  |  2       | 20
2  |  1       | 40
SELECT ID,Name,[Version],Code
FROM (
        SELECT ROW_NUMBER() OVER (PARTITION BY NAME ORDER BY [Version] DESC) AS RNK,*
        FROM
            (
                SELECT 1 ID, 'A' Name ,1 [Version] ,10 Code
                UNION ALL
                SELECT 1, 'A', 2 ,20
                UNION ALL
                SELECT 1, 'A', 3 ,30
                UNION ALL
                SELECT 1, 'A', 4 ,NULL
                UNION ALL
                SELECT 2, 'B', 1 ,40
                UNION ALL
                SELECT 2, 'B', 2 ,50
                UNION ALL
                SELECT 2, 'C', 1 ,60
            )B
        )BASE
WHERE RNK =2

我已经测试了下面的代码,它根据您期望的查询结果给出了输出

ID |  Version | Code
------------------------
1  |  2       | 20
2  |  1       | 40
SELECT ID,Name,[Version],Code
FROM (
        SELECT ROW_NUMBER() OVER (PARTITION BY NAME ORDER BY [Version] DESC) AS RNK,*
        FROM
            (
                SELECT 1 ID, 'A' Name ,1 [Version] ,10 Code
                UNION ALL
                SELECT 1, 'A', 2 ,20
                UNION ALL
                SELECT 1, 'A', 3 ,30
                UNION ALL
                SELECT 1, 'A', 4 ,NULL
                UNION ALL
                SELECT 2, 'B', 1 ,40
                UNION ALL
                SELECT 2, 'B', 2 ,50
                UNION ALL
                SELECT 2, 'C', 1 ,60
            )B
        )BASE
WHERE RNK =2

谢谢你的建议Joeri-关于PK你是对的。。。ID是另一个表的唯一PK,我最终会将这些结果加入到这个表中,所以这可能是混淆的地方。尽管如此,这将是我在上面要求的结果表2的主键。你的解决方案对我来说不太管用,因为我实际上是在处理33k+行的数据,所以我需要比插入所有这些值更整洁的东西!谢谢你的建议Joeri-关于PK你是对的。。。ID是另一个表的唯一PK,我最终会将这些结果加入到这个表中,所以这可能是混淆的地方。尽管如此,这将是我在上面要求的结果表2的主键。你的解决方案对我来说不太管用,因为我实际上是在处理33k+行的数据,所以我需要比插入所有这些值更整洁的东西!感谢您提供的解决方案,但不幸的是,由于我实际处理的数据量为33000行,因此不实用。我已经更新了这个问题。感谢您提供的解决方案,但不幸的是,由于我实际处理的数据量为33000行,因此不实用。我已经更新了这个问题。感谢您提供的解决方案,但不幸的是,由于我实际处理的数据量为33000行,因此不实用。我已经更新了这个问题。根据您的表,您可以尝试以下操作:选择ID、名称、[版本]、代码从选择ID、名称、[版本]、代码、按名称划分的行数按[Version]排序按[Version]描述从[Your table Name]作为RNK基于其中的RNK=2Spot-on——这是一个解决方案,我已将其改为按版本进行分区,以适应我所期望的结果。非常感谢。感谢您提供的解决方案,但不幸的是,由于我实际处理的数据量为33000行,因此不实用。我已经更新了这个问题。根据您的表,您可以尝试以下操作:选择ID、名称、[版本]、代码从选择ID、名称、[版本]、代码、按名称划分的行数按[Version]排序按[Version]描述从[Your table Name]作为RNK基于其中的RNK=2Spot-on——这是一个解决方案,我已将其改为按版本进行分区,以适应我所期望的结果。非常感谢你。