根据字段的值设置行号

时间:2013-03-24 08:45:16

标签: sql-server-2008 tsql

我有一些返回类似

的查询
 Column 1   | Column 2   | Column 3   | 
 somevalue  | somevalue  | somevalue  | 

我应该如何修改我的陈述来获得这个?第3列来自DB,第4列应基于第3列

 Column 1   | Column 2   | Column 3   | Column 4 | 
 somevalue  | somevalue  | 1          | 1        |
 somevalue  | somevalue  | 0          | NULL     |
 somevalue  | somevalue  | 0          | NULL     |
 somevalue  | somevalue  | 1          | 2        |
 somevalue  | somevalue  | 1          | 3        |

所以这不仅仅是简单的row_number()或rank()

查询

select SUBLVLNAME
,SPECGROUPNAME
,PRGNAME
,(REPLACE(SPECSUBGROUPCODE,'99999999','')) AS SPECSUBGROUPCODE
,SPECSUBGROUPNAME
,row_number() over( order by SPECSUBGROUPCODE) as ROW
,ADDACCR 
from
(
SELECT 
DISTINCT top 999999999
LOWER(EDU_SUBLEVELS.NAME) AS SUBLVLNAME
,SPECIALITY_GROUPS.NAME AS SPECGROUPNAME
,SPECIALITY_SUBGROUPS.NAME AS SPECSUBGROUPNAME
,case 
when EDU_SUBLEVELS.CODE not like 'Postgraduate' and EDU_SUBLEVELS.CODE not like 'void' then upper(substring(ACCREDITED_PROGRAMS.NAME,1,1)) + lower(substring(ACCREDITED_PROGRAMS.NAME,2, len(ACCREDITED_PROGRAMS.NAME)))
when EDU_SUBLEVELS.CODE like 'Postgraduate' then upper(substring(SPECIALITY_GROUPS.NAME,1,1)) + lower(substring(SPECIALITY_GROUPS.NAME,2, len(SPECIALITY_GROUPS.NAME)))
when EDU_SUBLEVELS.CODE like 'void' and SPECIALITY_SUBGROUPS.CODE is not null then upper(substring(SPECIALITY_GROUPS.NAME,1,1)) + lower(substring(SPECIALITY_GROUPS.NAME,2, len(SPECIALITY_GROUPS.NAME)))
end as PRGNAME
,ISNULL((case  
when EDU_SUBLEVELS.CODE =  'Postgraduate'  
then SPECIALITY_SUBGROUPS.CODE
when EDU_SUBLEVELS.CODE like 'void' and SPECIALITY_SUBGROUPS.CODE is not null then SPECIALITY_SUBGROUPS.CODE
end),'99999999') as SPECSUBGROUPCODE
,ACCREDITED_PROGRAMS.HAS_ADDITIONAL_ACCREDITED_PROGRAMS AS ADDACCR 

FROM ACCREDITED_PROGRAMS 
LEFT JOIN CERTIFICATE_SUPPLEMENTS ON ACCREDITED_PROGRAMS.CERTIFICATE_SUPPLEMENT_FK = CERTIFICATE_SUPPLEMENTS.ID 
LEFT JOIN SPECIALITY_SUBGROUPS ON ACCREDITED_PROGRAMS.SPECIALITY_SUBGROUP_FK = SPECIALITY_SUBGROUPS.ID 
LEFT JOIN SPECIALITY_GROUPS ON SPECIALITY_SUBGROUPS.SPECIALITY_GROUP_FK = SPECIALITY_GROUPS.ID 
LEFT JOIN EDU_SUBLEVELS ON SPECIALITY_GROUPS.EDU_SUB_LEVEL_FK = EDU_SUBLEVELS.ID 
LEFT JOIN EDU_LEVELS ON EDU_SUBLEVELS.EDU_LEVEL_FK = EDU_LEVELS.ID

WHERE     
CERTIFICATE_SUPPLEMENTS.ID = '2e1b2dec-ab81-4191-a423-97f3ac9c88e2' and EDU_LEVELS.CODE = 'PostHigh'

) as outq

UPD1:

DECLARE @COLUMN3Count int
SELECT @COLUMN3Count = COUNT(HAS_ADDITIONAL_ACCREDITED_PROGRAMS) FROM ACCREDITED_PROGRAMS WHERE HAS_ADDITIONAL_ACCREDITED_PROGRAMS = 0

SELECT *,row,
       CASE WHEN ADDACCR = 0 THEN NULL 
       ELSE ROW_NUMBER() OVER (ORDER BY SPECGROUPCODE) - @COLUMN3Count
       END AS Footnote

FROM (SELECT DISTINCT top 99999999
dense_rank() OVER(ORDER BY SPECIALITY_GROUPS.CODE) AS ROW,
EDU_SUBLEVELS.ORDERING,
EDU_LEVELS.CODE, EDU_LEVELS.NAME AS EDU_LEVEL,
LOWER(EDU_LEVELS.NAME) AS EDU_LEVEL2,
EDU_SUBLEVELS.CODE  AS SUBLVLCODE,
EDU_SUBLEVELS.NAME AS SUBLVLNAME,
SPECIALITY_GROUPS.CODE AS SPECGROUPCODE,
UPPER(SUBSTRING(SPECIALITY_GROUPS.NAME,1,1)) + LOWER(SUBSTRING(SPECIALITY_GROUPS.NAME,2, LEN(SPECIALITY_GROUPS.NAME)))  AS SPECGROUPNAME,
CASE
when EDU_SUBLEVELS.CODE ='Magistracy' then 'магистр'
when EDU_SUBLEVELS.CODE ='Specialty' then 'специалист'
when EDU_SUBLEVELS.CODE ='Undergraduate' then 'бакалавр'
END AS QUALNAME,
case
when EDU_SUBLEVELS.NAME ='Специалитет' then 'подготовка специалиста'
when EDU_SUBLEVELS.NAME ='Магистратура' then lower(EDU_SUBLEVELS.NAME)
when EDU_SUBLEVELS.NAME ='Бакалавриат' then lower(EDU_SUBLEVELS.NAME)
END AS SUBLVLNAMEHEADER,
HAS_ADDITIONAL_ACCREDITED_PROGRAMS as ADDACCR

FROM ACCREDITED_PROGRAMS 
LEFT JOIN CERTIFICATE_SUPPLEMENTS ON ACCREDITED_PROGRAMS.CERTIFICATE_SUPPLEMENT_FK = CERTIFICATE_SUPPLEMENTS.ID 
LEFT JOIN SPECIALITY_SUBGROUPS ON ACCREDITED_PROGRAMS.SPECIALITY_SUBGROUP_FK = SPECIALITY_SUBGROUPS.ID 
LEFT JOIN SPECIALITY_GROUPS ON SPECIALITY_SUBGROUPS.SPECIALITY_GROUP_FK = SPECIALITY_GROUPS.ID 
LEFT JOIN EDU_SUBLEVELS ON SPECIALITY_GROUPS.EDU_SUB_LEVEL_FK = EDU_SUBLEVELS.ID 
LEFT JOIN EDU_LEVELS ON EDU_SUBLEVELS.EDU_LEVEL_FK = EDU_LEVELS.ID

WHERE     CERTIFICATE_SUPPLEMENTS.ID = 'eb22a2fb-929e-4b4f-9716-23d9e340cd4b'and EDU_LEVELS.CODE = 'High' and EDU_SUBLEVELS.CODE = 'Specialty'
) as tmp

输出int

SPECGROUPCODE   ADDACCR row Footnote
010000          0         1 NULL
020000          0         2 NULL
030000          0         3 NULL
030000          1         3 -138858

输出位

SPECGROUPCODE   ADDACCR row Footnote
010000          0       1   NULL
020000          0       2   NULL
030000          0       3   NULL
030000          1       3   3

另外正如你可以看到这个解决方案在第三排中有所不同,我怎么能避免这种情况?

2 个答案:

答案 0 :(得分:1)

考虑到您在问题中提供的示例,您可以执行以下操作:

DECLARE @COLUMN3Count INT
SELECT @COLUMN3Count = COUNT(COLUMN3) FROM TABLE1 WHERE COLUMN3 = 0

SELECT *,
       CASE WHEN COLUMN3 = 0 THEN NULL 
       ELSE ROW_NUMBER() OVER (ORDER BY COLUMN3) - @COLUMN3Count
       END AS COLUMN4
FROM yourTABLE

SQL FIDDLE DEMO

答案 1 :(得分:1)

步骤1.在您的PARTITION BY电话中引入ROW_NUMBER,分别枚举1和0,即代替

ROW_NUMBER() OVER (ORDER BY ...) AS Column4

使用

ROW_NUMBER() OVER (PARTITION BY Column3 ORDER BY ...) AS Column4

步骤2.介绍CASE以有条件地显示ROW_NUMBER的结果:

CASE Column3
  WHEN 1 THEN ROW_NUMBER() OVER (PARTITION BY Column3 ORDER BY ...)
END AS Column4

如果省略ELSE表达式的CASE部分,则隐含ELSE NULL。因此,如果Column3不是1,则表达式将计算为NULL。