2010-08-20 14 views
0

J'ai une requête que je n'arrive pas à faire fonctionner correctement. J'ai 3 tables; Personne, PersonneProgramme et Catégorie.Requête avec priorité

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

La table personne a 1 dossier pour chaque personne et le PersonProgram a plusieurs programmes par personne. Il y a 4 catégories et j'ai besoin de tirer dans une seule rangée, de chaque personne, avec le programme spécifique de chaque catégorie.

Personne Tableau:

1 
2 
3 

PersonProgram Tableau

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

Quel devrait être le résultat souhaité:

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

Le problème est qu'il ya plusieurs enregistrements de programme pour chaque personne et catégorie avec un code de 1, 2 ou 3. Je dois mettre la priorité sur le code 1 puis le code 3 et igno Re le reste, tout en tirant seulement 1 enregistrement, ou NULL s'il n'existe pas. Je le perds en essayant de faire fonctionner cela.

FYI, il doit être dans une vue.

Merci pour toute aide.

Répondre

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 

Retours

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

Ceci est différent de vos résultats attendus. (même si je peux faire la même chose en utilisant pp2.Category plutôt que pp2.ID) Pouvez-vous clarifier?

+1

Les résultats de mon exemple étaient probablement faux, WAY à long avec cette requête. Je vais regarder ça, ça a l'air très prometteur. Quitter l'heure le vendredi :) –

+0

Peut-on utiliser 'ROW_NUMBER' dans une vue? Si je l'ajoute, SSMS se bloque à chaque fois. Utilisation de SQL 2005. –

+0

@durilai - Oui. Si le concepteur ne peut pas faire face à cela, essayez de le faire via le script 'CREATE VIEW dbo.ViewName AS AVEC pp2 AS ...' –