仅从临时表中选择所有第二高值

时间:2015-08-04 08:43:57

标签: sql-server tsql sql-server-2008-r2

使用T-SQL(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

为了达到这个目的,我需要调整下面的查询以获得第二个最高值,只要结果给出的版本号大于1.这些结果来自临时表,然后放入最终结果temp表。 编辑:请注意这将应用于超过33000行的数据,所以我更喜欢比INSERT VALUES更整洁的东西。感谢。

当前查询:

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 < (SELECT MAX(VERSION) FROM #TABLE 2),但这没有任何效果,可能是由于唯一的代码值,并且在任何情况下都无法在我拥有3个以上版本的情况下工作。

我们将非常感激。

提前致谢。

3 个答案:

答案 0 :(得分:0)

如果您的主键只是ID,则表示您有重复的行。所以我假设你的主键是别的东西,例如ID,Version,Name。您有两个具有相同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]

我必须用最外面的选择做一个小肮脏的把戏,这是因为重复的&#39; Id&#39;和&#39;版本&#39;。否则你会得到ID = 2,Version = 1

的两行

如果要删除NULL值,可以更改WITH部分(根据上次编辑):

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

答案 1 :(得分:0)

试试这个:

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

答案 2 :(得分:0)

我已经测试了以下代码并且按照您的预期结果提供了输出

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