2012-10-05 3 views
0

J'ai écrit une procédure stockée:Comment utiliser EXCEPT dans cette procédure stockée?

SELECT 
    Encounter.EncounterNumber, 
    substring(Encounter.EncounterNumber,4,9) as Acct, 
    MedicalRecordNumber, 
    [AdmitDate - CCYYMMDD] as AdmitDate, 
    [DischargeDate - CCYYMMDD] as DischDate, 
    DischargeDisposition, 
    Encounter.Age, 
    EnctrAPR.APRDRG, 
    Age18, Age18To64, Age65 
from 
    Encounter 
    full outer join EnctrAPR on 
     substring(Encounter.EncounterNumber,4,9) = EnctrAPR.EncounterNumber 
where 
    HSP# = 1 
    and InOutCode = 'I' 
    and ActualTotalCharge >0 
    and AdmitSubService <> 'SIG' 
    and [DischargeDate - CCYYMMDD] between @StartDate and @EndDate 
    and Encounter.Age >= 18 

Je voudrais utiliser les directives EXCEPT ou INTERSECT pour me montrer des lignes qui ne sont pas EnctrAPR qui sont en Encounter. Notez que j'ai différents formats EncounterNumber sur les deux tables.

Comment est-ce que j'accomplirais ceci?

+0

Si les chiffres sont différents formats alors comment voulez-vous les faire correspondre? Est-ce basé sur tous les autres domaines? – JNK

+0

La valeur EncounterNumber dans Encounter est varchar (20) et EncounterNunber dans EnctrAPR est varchar (50). Les valeurs de la table Encounter sont pré-affectées avec 001, d'où la nécessité d'une sous-chaîne pour joindre les deux tables. Dois-je ajouter le 001 à EncounterNumber dans EnctrAPR pour EXCEPT ou INTERSECT pour travailler? – SidC

+0

'EXCEPT' et' INTERSECT' regardent toutes les valeurs sur une ligne, donc oui. Sinon, les champs 'EncounterNumber' ne correspondront jamais correctement. – JNK

Répondre

1

Vous n'avez pas vraiment besoin d'intersection ou à l'exception de ce que vous cherchez mais vous pourriez le faire de cette façon.

SELECT Encounter.EncounterNumber, substring(Encounter.EncounterNumber,4,9) as Acct, 
MedicalRecordNumber, [AdmitDate - CCYYMMDD] as AdmitDate, [DischargeDate - CCYYMMDD] as 
DischDate, DischargeDisposition, Encounter.Age, EnctrAPR.APRDRG, Age18, Age18To64, Age65 
from Encounter 
full outer join EnctrAPR on 
substring(Encounter.EncounterNumber,4,9) = EnctrAPR.EncounterNumber 
where HSP# = 1 
and InOutCode = 'I' 
and ActualTotalCharge >0 
and AdmitSubService <> 'SIG' 
and [DischargeDate - CCYYMMDD] between @StartDate and @EndDate 
and Encounter.Age >= 18 
INTERSECT -- OR EXCEPT 
SELECT Encounter.EncounterNumber, substring(Encounter.EncounterNumber,4,9) as Acct, 
MedicalRecordNumber, [AdmitDate - CCYYMMDD] as AdmitDate, [DischargeDate - CCYYMMDD] as 
DischDate, DischargeDisposition, Encounter.Age, EnctrAPR.APRDRG, Age18, Age18To64, Age65 
from EnctrAPR 
join Encounter on 
substring(Encounter.EncounterNumber,4,9) = EnctrAPR.EncounterNumber 
where HSP# = 1 
and InOutCode = 'I' 
and ActualTotalCharge >0 
and AdmitSubService <> 'SIG' 
and [DischargeDate - CCYYMMDD] between @StartDate and @EndDate 
and Encounter.Age >= 18 

Vous pourriez l'accomplir de cette façon, mais je ne le recommanderais pas. C'est un peu une approche de force brute. Pour obtenir uniquement les enregistrements qui sont dans EnctrAPR, vous pouvez modifier votre FROM EnctrAPR et utiliser une jointure interne à Encounter.

SELECT Encounter.EncounterNumber, substring(Encounter.EncounterNumber,4,9) as Acct, 
MedicalRecordNumber, [AdmitDate - CCYYMMDD] as AdmitDate, [DischargeDate - CCYYMMDD] as 
DischDate, DischargeDisposition, Encounter.Age, EnctrAPR.APRDRG, Age18, Age18To64, Age65 
from EnctrAPR 
join Encounter on 
substring(Encounter.EncounterNumber,4,9) = EnctrAPR.EncounterNumber 
where HSP# = 1 
and InOutCode = 'I' 
and ActualTotalCharge >0 
and AdmitSubService <> 'SIG' 
and [DischargeDate - CCYYMMDD] between @StartDate and @EndDate 
and Encounter.Age >= 18 

Pour obtenir uniquement les enregistrements qui n'existent pas dans EnctrApr j'utiliser une jointure gauche:

SELECT Encounter.EncounterNumber, substring(Encounter.EncounterNumber,4,9) as Acct, 
MedicalRecordNumber, [AdmitDate - CCYYMMDD] as AdmitDate, [DischargeDate - CCYYMMDD] as 
DischDate, DischargeDisposition, Encounter.Age, EnctrAPR.APRDRG, Age18, Age18To64, Age65 
from Encounter 
left outer join EnctrAPR on 
substring(Encounter.EncounterNumber,4,9) = EnctrAPR.EncounterNumber 
where HSP# = 1 
and InOutCode = 'I' 
and ActualTotalCharge >0 
and AdmitSubService <> 'SIG' 
and [DischargeDate - CCYYMMDD] between @StartDate and @EndDate 
and Encounter.Age >= 18 
and EnctrAPR.EncounterNumber IS NULL 
+0

La dernière ligne de votre exemple de jointure externe gauche me donne une erreur indiquant le nom de colonne Invalid EnctrAPR. Dois-je remplacer cela par EnctrAPR.EncounterNumber? – SidC

+0

Votre droit. Mis à jour maintenant – jTC

+0

Intercept et Except sont sauvagement utilisés sous IMO. Mais dans ce cas, vous faites essentiellement la requête deux fois sans beaucoup de gains. Je les utilise pour isoler les identifiants d'un certain nombre de tables, car ils sont incroyablement rapides comparés à l'utilisation de jointures pour obtenir les mêmes données. – jTC

1

Pour obtenir seulement ces documents qui sont Encounter et non pas dans EnctrAPR, puis il suffit d'utiliser left outer join au lieu de full outer join, et ajouter une clause excluant les valeurs nulles pour EnctrAPR.EncounterNumber.

à savoir

SELECT 
    Encounter.EncounterNumber, 
    substring(Encounter.EncounterNumber,4,9) as Acct, 
    ... 
    EnctrAPR.APRDRG, 
    Age18, Age18To64, Age65 
from 
    Encounter 
    left outer join EnctrAPR on 
     substring(Encounter.EncounterNumber,4,9) = EnctrAPR.EncounterNumber 
where 
    EnctrAPR.EncounterNumber is null 
    and HSP# = 1 
    and InOutCode = 'I' 
    and ActualTotalCharge >0 
    and AdmitSubService <> 'SIG' 
    and [DischargeDate - CCYYMMDD] between @StartDate and @EndDate 
    and Encounter.Age >= 18 

Notez cependant que la valeur de EnctrAPR.APRDRG sera toujours nulle, comme EnctrAPR ne dispose pas d'une ligne correspondante.

+0

Une façon plus efficace de faire cela est d'utiliser 'NOT EXISTS' -' LEFT OUTER JOIN' est plus lent et a également le potentiel de créer des doublons – JNK

+0

C'est une alternative. Juste pour noter cependant que dans ce cas, il n'y aura pas de doublons car il n'y a qu'une seule paire de champs correspondants dans la jointure, et la clause where supprime ces enregistrements de la table de droite qui satisfont la jointure, même s'il y avait _were_ 2 enregistrements rhs pour chaque enregistrement lhs, ils n'apparaissent pas. –

Questions connexes