2010-08-20 102 views
0

我有一个查询,我无法正常工作。我有3张桌子; Person,PersonProgram和Category。优先查询

Person: ID, ....  
PersonProgram: ID, PersonID, Category, Code ...  
Category: ID, ... 

Person表对每个人有1条记录,PersonProgram对每个人有多个程序。有四个类别,我需要拉入每个人的单行,并与每个类别的特定程序。

人表:

1 
2 
3 

PersonProgram表

1, 1, 1, 1 
2, 1, 2, 1 
3, 1, 1, 3 
4, 2, 1, 1 
5, 2, 3, 3 

期望的结果应该是什么:

PersonID, ProgramIDforCat1, ProgramIDforCat2, ProgramIDforCat3, ProgramIDforCat4 
1, 1, 2, NULL, NULL 
2, 1, NULL, 3, NULL 

的问题是,有每个人的多个程序记录和类别代码为1,2或3.我需要优先考虑代码1,然后代码3和忽略剩下的只剩下1条记录,如果不存在则返回NULL。

我失去它试图让它工作。

仅供参考,它必须在视图中。

感谢您的任何帮助。

回答

1
WITH Person AS 
(
SELECT 1 AS ID UNION ALL 
SELECT 2 AS ID UNION ALL 
SELECT 3 AS ID 
), 
PersonProgram AS 
(
SELECT 1 AS ID, 1 AS PersonID, 1 AS Category, 1 AS Code UNION ALL 
SELECT 2, 1, 2, 1 UNION ALL 
SELECT 3, 1, 1, 3 UNION ALL 
SELECT 4, 2, 1, 1 UNION ALL 
SELECT 5, 2, 3, 3 
), 
pp2 AS 
(
SELECT * 
,ROW_NUMBER() OVER 
(PARTITION BY PersonID, Category 
     ORDER BY CASE WHEN Code = 1 THEN 0 ELSE 1 END, 
       CASE WHEN Code = 3 THEN 0 ELSE 1 END) AS RN 
FROM PersonProgram 
) 
select PersonID , 
max(case when Category =1 then pp2.ID end) ProgramIDforCat1, 
max(case when Category =2 then pp2.ID end) ProgramIDforCat2, 
max(case when Category =3 then pp2.ID end) ProgramIDforCat3, 
max(case when Category =4 then pp2.ID end) ProgramIDforCat4 
from Person p join pp2 
on pp2.PersonID = p.ID 
WHERE RN=1 
group by PersonID 

返回

PersonID ProgramIDforCat1 ProgramIDforCat2 ProgramIDforCat3 ProgramIDforCat4 
----------- ---------------- ---------------- ---------------- ---------------- 
1   1    2    NULL    NULL 
2   4    NULL    5    NULL 

这是从你期望的结果不同。 (尽管我可以通过使用pp2.Category而不是pp2.ID来达到同样效果)你能澄清一下吗?

+1

在我的例子中的结果可能是错误的,方式长这个查询。我会看看这个,看起来很有前途。周五放弃时间:) – 2010-08-20 22:59:09

+0

在视图中可以使用'ROW_NUMBER'吗?如果我添加SSMS每次崩溃。使用SQL 2005. – 2010-08-23 15:55:03

+0

@durilai - 是的。如果设计者无法应付它,试着通过脚本'CREATE VIEW dbo.ViewName AS WITH pp2 AS ...'来做到这一点'' – 2010-08-23 15:59:12