À titre d'exemple, j'ai un tableau comme celui-ci:
SELECT * FROM (
SELECT
md.week_dt,
md.cust,
md.y_w,
md.y,
md.w,
md.y_fp,
FROM MASTER_DATES md
) t1
Where
t1.week_dt IN (
SELECT TOP(1) t2.week_dt
FROM MASTER_DATES t2
WHERE t2.week_dt = t1.week_dt AND t2.cust = t1.cust
ORDER BY t2.week_dt
)
ORDER BY t1.week_dt
La dernière colonne contient des informations sur l'année / la période fiscale. Je voudrais sélectionner une ligne pour chaque élément y_fp avec week_dt et y_w étant la première date pour cette année / période fiscale. Ainsi, choisir parmi les éléments ci-dessus donnerait:
week_dt cust y_w w y y_fp 2011-01-29 ABC 201122 6 2011 201106 2011-02-19 ABC 201125 7 2011 201107 2011-03-19 ABC 201129 8 2011 201108 2011-04-16 ABC 201133 9 2011 201109
J'ai essayé de suivre cet exemple en utilisant TOP (1) au lieu de LIMIT mais j'ai le tableau entier me revint.
Voici ma requête:
week_dt cust y_w w y y_fp 2011-01-29 ABC 201122 6 2011 201106 2011-02-05 ABC 201123 6 2011 201106 2011-02-12 ABC 201124 6 2011 201106 2011-02-19 ABC 201125 7 2011 201107 2011-02-26 ABC 201126 7 2011 201107 2011-03-05 ABC 201127 7 2011 201107 2011-03-12 ABC 201128 7 2011 201107 2011-03-19 ABC 201129 8 2011 201108 2011-03-26 ABC 201130 8 2011 201108 2011-04-02 ABC 201131 8 2011 201108 2011-04-09 ABC 201132 8 2011 201108 2011-04-16 ABC 201133 9 2011 201109 2011-04-23 ABC 201134 9 2011 201109
Notez que MASTER_DATES contient une clé primaire composite des colonnes week_dt et cust .
3 Réponses :
Essayez d'utiliser row_number et une partition by pour le diviser par md.y_fp
WITH C AS(
SELECT
md.week_dt,
md.cust,
md.y_w,
md.y,
md.w,
md.y_fp,
row_number() over(partition by md.y_fp order by md.week_dt asc) as rn
FROM MASTER_DATES md
)
SELECT *
FROM C
WHERE RN = 1
Une méthode est row_number():
select md.*
from master_dates md
where md.week_date = (select min(md2.week_date)
from master_dates md2
where md2.cust = md.cust and md2.y_fp = md.y_fp
);
Dans certains cas, cependant, une sous-requête corrélée a de meilleures performances:
select md.*
from (select md.*,
row_number() over (partition by md.cust, md.y_fp order by md.week_date desc) as seqnum
from master_dates md
) md
where seqnum = 1;
Vos exemples de données et les résultats attendus indiquent qu'un simple groupement par est suffisant:
select min(week_dt) week_dt, cust, min(y_w) y_w, w, y, y_fp from MASTER_DATES group by cust, y, w, y_fp
Désolé, la colonne y en double était un accident. Je vais éditer ça. Et oui, cela semble avoir fonctionné aussi et c'est très simple.
Vous avez besoin d'un regroupement et des valeurs minimales de 2 colonnes. C'est tout.