Disons que j'ai la table SQL suivante (avec la clé primaire: date),
date foo -------- ---- 20181001 NULL 20181101 10 20181201 NULL 20190101 1
Comment puis-je obtenir la première valeur non nulle de la colonne "foo", p>
Quelle fonction serveur SQL dois-je utiliser? Veuillez aider avec une fonction qui est plus rapide pour les grandes tables avec ~ 1 million d'enregistrements.
5 Réponses :
Nous pouvons utiliser ROW_NUMBER:
SELECT date, foo FROM cte WHERE rn = 1 AND date BETWEEN '20181001' AND '20181101';
Si vous souhaitez également limiter à une certaine plage de dates, ajoutez-le simplement au WHERE code> clause:
WITH cte AS (
SELECT date, foo, ROW_NUMBER() OVER (ORDER BY date) rn
FROM yourTable
WHERE foo IS NOT NULL
)
SELECT date, foo
FROM cte
WHERE rn = 1;
Comment puis-je faire fonctionner cela pour plusieurs valeurs? Veuillez vous référer à ma dernière modification.
J'ai retourné votre question à ce que vous aviez demandé au départ. Il est impoli et mauvais de faire sur ce site des changements importants à votre question après que de nombreux utilisateurs y ont déjà répondu. Si vous rencontrez un autre problème, vous pouvez poser une nouvelle question.
Assurez-vous d'avoir un index d'index composite approprié sur
where foo is not null
et un filtre pour
(foo, date)
SELECT TOP 1 date FROM table WHERE date IS NULL ORDER BY date DESC Select the null valued rows, order them desc by date, then select the top result. Should return the correct value.
La requête est simplement:
create index idx1 on mytable (date, foo); create index idx2 on mytable (foo, date);
Ensuite, vous auriez un index pour un accès rapide. Je fournirais les deux suivants:
select top(1) foo from mytable where date between '20181001' and '20181101' and foo is not null order by date;
Le SGBD choisira l'un ou l'autre ou aucun d'entre eux en fonction de la sélectivité.
Je suppose que vous souhaitez commander les dates. Sinon, vous ne pourrez pas trouver la première valeur foo non nulle. Parce que le terme premier est relatif. Vous devez avoir une clause order by pour trouver la première valeur non nulle.
J'ai donné un exemple de code pour votre référence.
CREATE TABLE #test (datevalue DATE, foo INT);
CREATE CLUSTERED INDEX cix_test ON #test (datevalue);
INSERT INTO #test
VALUES ('20181001', NULL), ('20181101', 10), ('20181201', NULL), ('20190101', 1);
SELECT TOP 1 FIRST_VALUE(foo) OVER (
ORDER BY datevalue
)
FROM #test
WHERE datevalue BETWEEN '20181001'
AND '20181101'
AND foo IS NOT NULL;
Comment puis-je faire en sorte que cela fonctionne pour plusieurs colonnes avec des valeurs de date différentes pour chaque colonne?
@deepak, comme l'a dit Tim Biegeleisen, je vous suggère de créer une autre question pour éviter toute confusion pour les futurs visiteurs de cette question
La requête semble inappropriée, car elle récupère cette première valeur multiple, car vous utilisez une fonction analytique. Ainsi, avec mille valeurs dans la plage de dates, vous obtenez un résultat de mille lignes affichant toutes la première valeur. Vous pouvez bien sûr appliquer DISTINCT sur le résultat, mais c'est un peu gênant à mon avis.
@ThorstenKettner, j'ai préparé la requête en fonction de l'ensemble de données d'entrée que l'utilisateur avait donné. Vous avez raison. J'ai mis à jour ma réponse.
Pouvez-vous montrer votre jeu de résultats attendu?
@dnoeth, a mis à jour la question avec des exemples d'entrée et de sortie.