Filtrage SQL sur plusieurs dates avec plusieurs colonnes

J'essaie d'extraire les loggings qui sont filtrés par deux colonnes de date. J'ai besoin de montrer tous les loggings "actifs". Actuellement, je peux extraire des loggings en utilisant la dernière date d'input en vigueur, mais le problème est que je peux avoir des loggings actifs sur plusieurs dates d'input en vigueur.

Un logging «actif» est défini comme un logging dont la date d'input en vigueur est antérieure ou égale à la date du jour (voir les notes relatives aux hypothèses de la date actuelle) et dont la date de fin est égale ou supérieure à la date actuelle. Un logging "inactif" serait les première et deuxième lignes de données dans mon exemple, un logging actif serait la troisième ligne de données.

Je travaille avec un set de données similaire à celui-ci:

+-------------+----------------+----------+---------+---------+---------+ | Mode Name | Effective Date | End Date | Mode ID | Param 1 | Param 2 | +-------------+----------------+----------+---------+---------+---------+ | Single Mode | 20110102 | 20120313 | 1 | Green | Metal | | Single Mode | 20120314 | 20131122 | 1 | Green | Wood | | Single Mode | 20131123 | 29991231 | 1 | Orange | Plastic | | Multi Mode | 20110102 | 20120313 | 5 | Orange | Plastic | | Multi Mode | 20120314 | 20120501 | 5 | Red | Metal | | Triple Mode | 20120314 | 20120314 | 3 | Blue | Cloth | | Triple Mode | 20120315 | 20131122 | 3 | Red | Wood | | Triple Mode | 20131123 | 20131130 | 3 | Red | Wood | | Triple Mode | 20131201 | 29991231 | 3 | Orange | Wood | | Double Mode | 20131123 | 29991231 | 2 | Green | Metal | | Double Mode | 20131202 | 29991231 | 2 | Brown | Plastic | | Quad Mode | 20131202 | 29991231 | 4 | Black | Wood | | Quad Mode | 20131203 | 29991231 | 4 | Green | Plastic | | Zero Mode | 20090704 | 29991231 | 0 | Blue | Cloth | +-------------+----------------+----------+---------+---------+---------+ 

Ce que je dois faire, c'est interroger afin que chaque mode "actif" soit affiché, mais seulement le dernier mode actif tel que défini par la colonne "date d'effet". Les modes "Terminé" ne devraient pas être affichés. Un mode "terminé" est défini comme ayant une date de fin antérieure à la date actuelle – avec "29991231" étant défini comme "aucune date de fin". Idéalement, l'set de données ci-dessus serait filterr à ceci:

 +-------------+----------------+----------+---------+---------+---------+ | Mode Name | Effective Date | End Date | Mode ID | Param 1 | Param 2 | +-------------+----------------+----------+---------+---------+---------+ | Single Mode | 20131123 | 29991231 | 1 | Orange | Plastic | | Triple Mode | 20131201 | 29991231 | 3 | Orange | Wood | | Double Mode | 20131202 | 29991231 | 2 | Brown | Plastic | | Quad Mode | 20131203 | 29991231 | 4 | Green | Plastic | | Zero Mode | 20090704 | 29991231 | 0 | Blue | Cloth | +-------------+----------------+----------+---------+---------+---------+ 

Quelques notes:

  1. Supposons que la «date actuelle» dans cet exemple est le 2013-12-16.
  2. Vous ne pouvez pas filterr uniquement à la date de fin. En raison du fonctionnement de notre système, la date de fin de "29991231" ne garantit pas la fin d'un logging. Par exemple, étant donné deux loggings avec des dates de fin de "29991231", celui avec la date d'input en vigueur la plus récente replacea celui avec une date d'input plus ancienne.
  3. Certains loggings ne seront pas affichés du tout car ils sont terminés avant la date actuelle.
  4. C'est un vieux système terriblement conçu. Je suis sûr qu'il y a une tonne de meilleures façons de stocker des données (croyez-moi, ce que je vous montre n'est pas la pire partie) – mais malheureusement, je suis coincé avec ce que j'ai.

Voici

 SELECT YourTable.ModeName, YourTable.EffectiveDate, YourTable.EndDate, YourTable.ModeId, YourTable.Param1, YourTable.Param2 FROM YourTable INNER JOIN (SELECT ModeName, MAX(EffectiveDate) AS MaximumEffectiveDate FROM YourTable AS YourTable_1 WHERE (GETDATE() BETWEEN CONVERT(Date, EffectiveDate, 101) AND CONVERT(Date, EndDate, 101)) GROUP BY ModeName) AS GroupedByMode ON YourTable.ModeName = GroupedByMode.ModeName AND YourTable.EffectiveDate = GroupedByMode.MaximumEffectiveDate 

Changez simplement le GETDATE() avec la date de votre choix

J'espère que c'est ce dont vous avez besoin, j'ai copié vos données et testé pour get les mêmes résultats que vous avez

entrez la description de l'image ici

Vous pouvez utiliser un CTE pour get le seul logging pour chacun:

 with MaxDate as (select [Mode Name], max([Effective Date]) as mdate from table1 group by [Mode Name]) select * from table1 t1 inner join MaxDate on mdate = [Effective Date] and t1.[Mode Name] = MaxDate.[Mode Name] where [End Date] = 29991231 

SQL Fiddle