(Advantage Database Server) J'ai une table de fournisseurs de services qui, à des fins d'audit, ne sont jamais supprimés. Ils ont une date de début et une date de fin; Dans le cas de modifications telles que le nom ou l'adresse, la ligne existante est finie, une nouvelle ligne est créée et une nouvelle date de début est affectée aux données modifiées.Correspondance d'une seule ligne spécifique dans un JOIN où plusieurs existent
Lors du traitement des paiements à ces fournisseurs, j'ai besoin d'une page récapitulative indiquant le nom du fournisseur, son adresse, son identifiant (ProvID) et le montant total payé. Ceci est fait dans une requête assez simple avec un SUM() et GROUP BY.
Le problème apparaît lorsqu'il existe deux ou plusieurs lignes pour un identificateur de fournisseur spécifié. Je me retrouve avec des lignes en double (ce qui pourrait entraîner des paiements multiples à ce fournisseur s'il n'est pas intercepté).
Ma première pensée était d'utiliser quelque chose (laid, mais réalise assez rapidement) comme une sous-sélection:
SELECT ... FROM service s
INNER JOIN provider p ON p.ProvID = s.ProvID
AND (p.EndDate IS NULL or p.EndDate = (SELECT Max(EndDate) FROM
provider lu WHERE lu.ProvID = s.ProvID))
Malheureusement, cela a fini par trouver encore deux rangées; une ligne pour le NULL EndDate et un pour le MAX (EndDate).
Je gérer cela dans d'autres cas (par exemple., La localisation du ProvID approprié pour un service fourni à une date précise) en utilisant
p.EndDate is null or (s.ServiceDate BETWEEN p.StartDate AND p.EndDate)
Malheureusement, étant donné que la requête de problème est GROUP BY avec un agrégat, la La date de service n'est pas disponible.
Des suggestions?
EDIT: Ce que je recherche est soit la ligne avec le NULL EndDate si elle existe, OU la ligne avec le Max (EndDate) si la ligne NULL n'existe pas. Cela couvre le cas, par exemple, où un fournisseur a été licencié hier, mais a travaillé la semaine dernière, et nous le paierons la semaine prochaine.
J'accepte cette réponse parce que c'est assez joli, et c'est légèrement plus rapide que la réponse NOT EXISTS de najmeddine (mais seulement légèrement en raison de la bonne sélection d'index). Merci, Kip. :-) –
Juste fusionné dans mon code et testé contre les données réelles. Fonctionne à 100%, sans perte de performance notable. Merci encore, Kip! NOTE POUR LES AUTRES UTILISATEURS ADS: Les appels COALESCE() nécessitent un ajout: Changez les deux à COALESCE (EndDate, CAST ('2037-01-01' AS SQL_DATE)), car ADS ne fait pas automatiquement la conversion à partir de la date littéraux comme les autres bases de données. –
@Ken White: Si vous avez plus d'une ligne avec la date de fin NULL, vous obtiendrez plus d'une ligne comme résultat. Je suppose que cela serait considéré comme des données corrompues dans votre schéma. – Kip