2010-02-04 6 views
0

J'ai une table qui ressemble à ceci:SQL. Comment travailler/comparer/trouver des différences au sein de différentes lignes dans la même table

ID Date  Size Marked 
1 2010-02-02 2  X 
2 2002-02-02 1 
1 2010-02-03 2  X 
2 2010-02-03 3   
3 2010-02-03 4  X 

Et j'ai un code (PHP) qui fait des choses suivantes: a) Calculer somme des tailles par jour b) Trouvez la différence entre le total pour ce jour et le dernier jour. c) Trouve la somme des tailles pour les rangées qui se sont marquées ce jour (la rangée avec le même identifiant n'a pas été marquée hier).

Comme exemple, je vais obtenir des résultats suivants:

Date  Total DiffWithYesterday MarkedThisDay 
2010-02-02 3  0     0 
2010-02-03 9  6     4 

Je sens qu'il ya une façon d'écrire ceci dans SQL. Cependant, je suis assez faible en SQL, donc j'ai abandonné après une journée à jouer autour des jointures internes, des sélections groupées et intégrées.

J'apprécierais, si vous me donnez quelques indices sur la façon de le faire.

Oh .. Et j'utilise MySQL.

Cordialement, Victor

Répondre

2

Quelque chose comme cela fonctionne dans SQL Server. Je n'ai pas MySQL à tester mais vous pouvez probablement convertir une fois que vous voyez la logique.

create table so (sodate datetime, sosize int, somarked varchar(1)) 

insert into so (sodate,sosize,somarked) values ('1-jan-2010',3,'X') 
insert into so (sodate,sosize,somarked) values ('2-jan-2010',1,'X') 
insert into so (sodate,sosize,somarked) values ('3-jan-2010',2,'X') 
insert into so (sodate,sosize,somarked) values ('4-jan-2010',0,null) 
insert into so (sodate,sosize,somarked) values ('5-jan-2010',2,null) 
insert into so (sodate,sosize,somarked) values ('6-jan-2010',1,null) 
insert into so (sodate,sosize,somarked) values ('6-jan-2010',4,null) 
insert into so (sodate,sosize,somarked) values ('6-jan-2010',1,null) 
insert into so (sodate,sosize,somarked) values ('7-jan-2010',3,'X') 
insert into so (sodate,sosize,somarked) values ('8-jan-2010',3,'X') 
insert into so (sodate,sosize,somarked) values ('9-jan-2010',2,null) 
insert into so (sodate,sosize,somarked) values ('10-jan-2010',2,'X') 
insert into so (sodate,sosize,somarked) values ('11-jan-2010',1,'X') 
insert into so (sodate,sosize,somarked) values ('12-jan-2010',2,null) 
insert into so (sodate,sosize,somarked) values ('13-jan-2010',3,'X') 

select so.sodate 
    ,sum(so.sosize) as Total 
    ,isnull(sum(so.sosize),0) - isnull(min(so2.sosize),0) as DiffFromYesterday 
    ,sum(case when so.somarked = 'X' then so.sosize end) as MarkedThisDay 
from so 
    left join (select so.sodate,sum(so.sosize) sosize from so group by sodate) so2 on dateadd(dd,1,so2.sodate) = so.sodate 
group by so.sodate 

..et après l'installation de MySQL cela semble y travailler ...

select so.sodate 
    ,sum(so.sosize) as Total 
    ,ifnull(sum(so.sosize),0) - ifnull(min(so2.sosize),0) as DiffFromYesterday 
    ,sum(case when so.somarked = 'X' then so.sosize end) as MarkedThisDay 
from so 
    left join (select so.sodate,sum(so.sosize) sosize from so group by sodate) so2 on (so2.sodate + INTERVAL 1 day)= so.sodate 
group by so.sodate ; 
+0

Merci. Cela a fonctionné comme un charme :) J'ai été capable de comprendre comment l'adopter à MySQL, quand j'ai vu la première réponse. –

2

avait du plaisir avec celui-ci.

SELECT 
    today.date as Date, 
    today.total as Total, 
    (today.total - yesterday.total) as DiffWithYesterday , 
    marked.total as MarkedThisDay 
FROM 
    (SELECT date, sum(size) as total 
    FROM table_name 
    GROUP BY date) today 
LEFT JOIN 
    (SELECT date, sum(size) as total 
    FROM table_name 
    WHERE marked = 'X' 
    GROUP BY date) marked ON today.date = marked.date 
LEFT JOIN 
    (SELECT (date + INTERVAL 1 day) as date, sum(size) as total 
    FROM table_name 
    GROUP BY date) yesterday ON today.date=yesterday.date 

De toute évidence, vous devrez remplacer "table_name" avec le nom de votre table