J'ai une table:
SELECT DISTINCT [Day], CASE WHEN Client_ID = '1804' THEN 1 ELSE 0 END AS Occur FROM table
Maintenant, ce que je veux faire, c'est prendre des valeurs distinctes de chaque colonne et (probablement avec une instruction while) vérifier toutes les valeurs de colonne de date et en avoir une plus de colonne avec une déclaration vrai ou faux si cet identifiant était à cette date. Le résultat devrait donc ressembler à ceci:
Day Client_ID Occur ------------------------- 2018.10.22 1804 TRUE 2018.10.23 1804 TRUE 2018.10.24 1804 TRUE 2018.10.25 1804 TRUE 2018.10.26 1804 TRUE 2018.10.29 1804 TRUE 2018.10.30 1804 TRUE 2018.10.31 1804 TRUE 2018.11.02 1804 TRUE 2018.11.23 1804 FALSE 2018.10.22 1317 Does not exist 2018.10.23 1317 Does not exist 2018.10.24 1317 TRUE 2018.10.25 1317 FALSE 2018.10.26 1317 FALSE 2018.10.29 1317 FALSE 2018.10.30 1317 FALSE 2018.10.31 1317 FALSE 2018.11.02 1317 FALSE 2018.11.23 1317 TRUE
Pour 1 ID, je peux obtenir le résultat avec cette requête:
Client_ID Day ------------------ 1804 2018-10-22 1804 2018-10-23 1804 2018-10-24 1804 2018-10-25 1804 2018-10-26 1804 2018-10-29 1804 2018-10-30 1804 2018-10-31 1804 2018-11-02 1317 2018-10-24 1317 2018-11-23
Mais j'en ai besoin pour parcourir toutes les valeurs distinctes de la colonne Day
. Et si la date la plus basse de certains ID est supérieure à la date la plus basse dans la colonne Jour, cela doit avoir un résultat différent. Disons que "n'existe pas" (mais cela peut être n'importe quoi). C'est là que j'ai besoin d'aide.
3 Réponses :
Ceci peut être réalisé avec un CROSS JOIN
qui génère toutes les combinaisons possibles de date et d'identifiant, combiné avec un LEFT JOIN
sur la table d'origine, comme:
SELECT d.date, i.id, CASE WHEN t.id IS NULL THEN 'FALSE' ELSE 'TRUE' END FROM (SELECT DISTINCT day FROM table) d CROSS JOIN (SELECT DISTINCT id FROM table) i LEFT JOIN table t ON t.date = d.date AND t.id = i.id
@Larnu: oui, merci de l'avoir signalé! J'étais en train de modifier en même temps que vous, je viens de mettre à jour ma réponse pour corriger cette faute de frappe
Cela a l'air vraiment sympa. Je vais l'essayer. J'ai juste oublié une chose en écrivant la demande originale et je n'ai pas remarqué qu'il y avait des réponses aussi rapidement lors de l'édition de mon message. Désolé pour ça.
Il existe un moyen de créer des boucles while sur SQL Server, vous pouvez essayer ceci:
DECLARE @intFlag INT SET @intFlag = 1 WHILE (@intFlag <= #Number of loops here) BEGIN #Your statements here SET @intFlag = @intFlag + 1 END
Ce n'est pas une mauvaise réponse, mais ce serait certainement l'une des pires performances. Juste une note aux lecteurs.
Convenu. Bien que l'OP ait supposé qu'il aurait probablement besoin d'une boucle WHILE
, en réalité en utiliser une serait un mauvais choix. SQL Server et d'autres SGBDR excellent dans les opérations basées sur des ensembles, pas dans les tâches itératives; et une boucle WHILE
est très certainement la dernière. Dans SQL World, de telles opérations sont appelées opérations RBAR (Row By Agonizing Row) et sont généralement mieux évitées.
Vous pouvez générer les lignes avec une jointure croisée
et utiliser jointure gauche
pour importer les valeurs. Vous avez besoin d'une contrainte supplémentaire sur la date la plus proche. Je pense que je ferais:
select d.date, c.client_id, (case when d.date < c.min_date then 'Does not exist' when t.id is not null then 'TRUE' else 'FALSE' end) as occur from (select distinct day from t) d cross join (select client_id, min(date) as min_date from <table> t group by client_id ) c left join <table> t on t.day = d.day and t.client_id = c.client_id;
Merci Gordon Linoff, c'est exactement ce dont j'avais besoin. Il y a juste une petite erreur, sur la seconde à partir de la ligne du bas avant "t" ou après la jointure gauche, il doit y avoir "table". Juste pour que les autres le sachent :)
Quelle version de SQL Server utilisez-vous?
Comme vous le verrez dans la discussion dans les réponses (ci-dessous), vous ne voulez pas utiliser une structure WHILE si vous pouvez l'éviter. Les systèmes SGBDR comme SQL Server sont BEAUCOUP plus heureux si vous leur confiez des tâches basées sur des ensembles.