2014-07-02 8 views
0

Je dois trouver les enregistrements actifs qui se situent entre une plage de paramètres de date à partir d'une table contenant des applications. Tout d'abord, je cherche un enregistrement entre la plage de dates dans une table appelée 'app_notes' et vérifie si elle est liée à une application. S'il n'y a pas d'enregistrement app_note dans la plage de dates, je dois regarder la note d'application la plus récente avant la plage de dates. Si cette note d'application indique un statut d'actif, je le sélectionne.Requête pour les enregistrements actifs entre la plage de dates ou la plage de dates la plus récente

La table app_indiv connecte un individu à une application. Il peut y avoir plusieurs enregistrements app_indiv pour chaque individu et plusieurs notes pour chaque app_indiv. Voici ce que j'ai jusqu'à présent:

SELECT DISTINCT individual.indiv_id 
    FROM individual INNER JOIN 
    app_indiv ON app_indiv.indiv_id = individual.indiv_id INNER JOIN 
    app_note ON app_indiv.app_indiv_id = app_note.app_indiv_id 
    WHERE (app_note.when_mod BETWEEN @date_from AND @date_to) 
    /* OR most recent app_note indicates active */ 

Comment puis-je obtenir le dernier dossier de app_note s'il n'y en a pas dans la plage de dates? Comme il y a plusieurs enregistrements app_note possibles, je ne sais pas comment faire pour récupérer uniquement les plus récents.

+0

C'est une exigence assez funky. Je dirais juste prendre une date maximum, et trouver l'enregistrement actif le plus récent avant cela. – Andrew

+0

Pouvez-vous s'il vous plaît publier le schéma de table pour la table app_note, et laissez-moi savoir s'il y a un app_note_id (ou équivalent) qui sera dans l'ordre de la plus récente app_note? Aussi, s'il vous plaît laissez-moi savoir si l'exigence «le plus récent» signifie la gamme de pré-date ou le maximum disponible – AHiggins

Répondre

0
SELECT * 
FROM individual i 
INNER JOIN app_indiv ai 
    ON ai.indiv_id = i.indiv_id 
OUTER APPLY 
(
    SELECT TOP 1 * FROM app_note an 
    WHERE an.app_indiv_id = ai.app_indiv_id 
     AND an.when_mod < @date_to 
    ORDER BY an.when_mod DESC 
) d 
WHERE d.status = 'active' 

Trouver la dernière note inférieure à la date de fin, vérifiez si elle est active et le cas échéant montrer le dossier individuel.

0

(non testé) Vous devez utiliser un commutateur CASE.

SELECT DISTINCT individual.indiv_id 
FROM individual INNER JOIN 
app_indiv ON app_indiv.indiv_id = individual.indiv_id INNER JOIN 
app_note ON app_indiv.app_indiv_id = app_note.app_indiv_id 
WHERE (CASE WHEN app_note.when_mod BETWEEN @date_from AND @date_to 
       THEN (SELECT appnote.when_mod from individual where appnote.when_mod BETWEEN @date_from AND @date_to) 
      WHEN app_note.when_mod NOT BETWEEN @date_from and @date_to 
       THEN (SELECT appnote.when_mod from individual appnote.when_mod LIMIT 1)) 

La requête n'est peut-être pas correcte. Il se peut que Switch doive être dans la première partie SELECT de la requête.

0

Il me semble que vous vous souciez vraiment de la date de fin de votre plage de dates, puisque vous voulez pouvoir regarder plus loin s'il n'y a rien dans cette plage de dates. J'utiliserais un CTE et la fonction ROW_NUMBER(). Le CTE est juste un moyen plus propre d'écrire une sous-requête (dans ce cas, un CTE peut en faire beaucoup plus). La fonction Row_Number numérotera les lignes en fonction de l'instruction order by. Le partition by réinitialise la numérotation à un chaque fois que vous tapez une nouvelle valeur dans cette colonne.

with AppNoteCTE as 
(select 
<not sure what columns you need here> 
app_indiv_id, 
ROW_NUMBER() OVER (PARTITION BY APP_INDIV_ID ORDER BY WHEN_MOD DESC) RN 
FROM 
APP_INDIV 
WHERE 
WHEN_MOD <= @endDate) 

SELECT DISTINCT individual.indiv_id 
    FROM individual INNER JOIN 
    app_indiv ON app_indiv.indiv_id = individual.indiv_id INNER JOIN 
    AppNoteCTE ON app_indiv.app_indiv_id = AppNoteCTE .app_indiv_id 
    and AppNoteCTE.RN = 1