2016-06-13 34 views
0
(Select top 1 pvd.Code from PatientVisitDiags pvd 
    where pvd.PatientVisitId = pv.PatientVisitId 
    Order By pvd.Listorder) as "DX1", 
(Select top 1 a.code from (Select top 2 pvd.Code,pvd.ListOrder from PatientVisitDiags pvd 
    where pvd.PatientVisitId = pv.PatientVisitId 
    Order By pvd.Listorder)a order by a.ListOrder DESC) as "DX2", 
(Select top 1 a.code from (Select top 3 pvd.Code,pvd.ListOrder from PatientVisitDiags pvd 
    where pvd.PatientVisitId = pv.PatientVisitId 
    Order By pvd.Listorder)a order by a.ListOrder DESC) as "DX3", 
(Select top 1 a.code from (Select top 4 pvd.Code,pvd.ListOrder from PatientVisitDiags pvd 
    where pvd.PatientVisitId = pv.PatientVisitId 
    Order By pvd.Listorder)a order by a.ListOrder DESC) as "DX4", 
(Select top 1 a.code from (Select top 5 pvd.Code,pvd.ListOrder from PatientVisitDiags pvd 
    where pvd.PatientVisitId = pv.PatientVisitId 
    Order By pvd.Listorder)a order by a.ListOrder DESC) as "DX5" 

上面的代码是我目前正在使用的(它不是最优的,但仅用于一次数据导出)。SQL Server 2008是否有可能具有选择最高返回空值

在我们当前正在导出的数据库中,有一个PatientVisitDiags表,它具有列“ListOrder”和“Code”。可以有1到5个代码。 ListOrder保存该代码的编号。例如:

ListOrder|Code | 
1  |M51.27 | 
2  |M54.17 | 
3  |G83.4 | 

我想将代码导出到新表(DX1,DX2..etc)中的相应列。如果我按ListOrder排序,我可以按照我需要的顺序(第1行到DX1 |第2行到DX2等)得到它们。但是,当我运行上述SQL代码时,如果源表只有3个代码,DX4和DX5将重复DX3 。例如:

DX1 |DX2 |DX3 |DX4 |DX5 
M51.27 |M54.17 |G83.4 |G83.4 |G83.4 

有没有办法让TOP返回NULL值,如果你选择TOP比给定的更多? SQL Sever 2008不支持OFFSET/FETCH,这是我通常会做的选择,以选择单独的行。

TL:DR

ID | Name 

1 | Joe 

2 | Eric 

3 | Steve 

4 | John 

如果我有一个表像上面并运行

SELECT TOP 5 Name FROM Table 

反正是有回报?

Joe 

Eric 

Steve 

John 

NULL 

回答

2

你真的在做什么是pivoting。所以枢轴!试试这个小查询:

WITH Top5 AS (
    SELECT TOP 5 
     Dx = 'DX' + Convert(varchar(11), Row_Number() OVER (ORDER BY pvd.Listorder)), 
     pvd.Code 
    FROM dbo.PatientVisitDiags pvd 
    WHERE pvd.PatientVisitId = @patientVisitId 
) 
SELECT * 
FROM 
    Top5 t 
    PIVOT (Max(Code) FOR Dx IN (DX1, DX2, DX3, DX4, DX5)) p 
; 

要回答你的第二个问题,关于得到非透视行集,基本上做同样的事情,但不知何故,提供了5行和左的连接到所需的数据。

WITH Data AS (
    SELECT TOP 5 
     Seq = Row_Number() OVER(ORDER BY ID), 
     Name 
    FROM dbo.Table 
    ORDER BY ID 
) 
SELECT 
    n.Seq, 
    t.Name 
FROM 
    (VALUES 
     (1), (2), (3), (4), (5) -- or a numbers-generating CTE perhaps 
    ) n (Seq) 
    LEFT JOIN Top 5 t 
     ON n.Seq = t.Seq 
; 

旁注

你正在做这样一个事实:

where pvd.PatientVisitId = pv.PatientVisitId 

告诉我你不使用ANSI连接。停止。不要再那样做了。将此连接条件放在JOINON子句中。这是2016年...为什么你使用上个世纪的连接语法?

噢,并在表名称上架构模式。查看它 - 你会发现实际的性能原因,为什么你应该这样做。这不只是要找到正确的模式所花费的时间,但也对执行计划缓存...

0

一次一个 - 回答问题的最后

创建表和一帮空

select top (5) col 
from 
(
select col from table1 
union 
select nulCol from nullTable 
) tt 
order by tt.col 
相关问题