2010-01-12 29 views
2

我正在寻找每个ID每天两个表之间的最大差异。我有一个MySQL数据库SQL子查询试图获得两个表中同一列的最大差异

insert into test.foo values ('2010-01-10', 1, 10); 
insert into test.foo values ('2010-01-10', 1, 5); 
insert into test.foo values ('2010-01-10', 2, 10); 
insert into test.foo values ('2010-01-10', 2, 10); 
insert into test.foo values ('2010-01-10', 3, 15); 
insert into test.foo values ('2010-01-10', 3, 15); 
insert into test.foo values ('2010-01-11', 1, 5); 
insert into test.foo values ('2010-01-11', 1, 5); 
insert into test.foo values ('2010-01-11', 2, 5); 
insert into test.foo values ('2010-01-11', 2, 5); 
insert into test.foo values ('2010-01-11', 3, 5); 
insert into test.foo values ('2010-01-11', 3, 5); 

insert into test.bar values ('2010-01-10', 1, 5); 
insert into test.bar values ('2010-01-10', 1, 5); 
insert into test.bar values ('2010-01-10', 2, 5); 
insert into test.bar values ('2010-01-10', 2, 5); 
insert into test.bar values ('2010-01-10', 3, 5); 
insert into test.bar values ('2010-01-10', 3, 5); 
insert into test.bar values ('2010-01-11', 1, 10); 
insert into test.bar values ('2010-01-11', 1, 10); 
insert into test.bar values ('2010-01-11', 2, 5); 
insert into test.bar values ('2010-01-11', 2, 5); 
insert into test.bar values ('2010-01-11', 3, 5); 
insert into test.bar values ('2010-01-11', 3, 5); 

在这里,下面的数据是我的查询:

SELECT t1.`date`, t1.id, t1.sums, t2.sums, max(t1.sums - t2.sums) FROM 
    (select `date`, id, sum(val) sums 
    from test.foo 
    group by `date`, id) as t1, 
    (select `date`, id, sum(val) sums 
    from test.bar 
    group by `date`, id) as t2 
WHERE t1.`date` = t2.`date` AND t1.id = t2.id 
group by t1.`date` 

我得到这个结果:

+---------------------+----+------+------+------------------------+ 
| date    | id | sums | sums | max(t1.sums - t2.sums) | 
+---------------------+----+------+------+------------------------+ 
| 2010-01-10 00:00:00 | 1 | 15 | 10 |      20 | 
| 2010-01-11 00:00:00 | 1 | 10 | 20 |      0 | 
+---------------------+----+------+------+------------------------+ 
2 rows in set (0.00 sec) 

我想收到此结果: 我得到这个结果:

+---------------------+----+------+------+------------------------+ 
| date    | id | sums | sums | max(t1.sums - t2.sums) | 
+---------------------+----+------+------+------------------------+ 
| 2010-01-10 00:00:00 | 1 | 15 | 10 |      20 | 
| 2010-01-11 00:00:00 | 2 | 10 | 10 |      0 | <----- 
+---------------------+----+------+------+------------------------+ 

任何人都可以帮助我吗?我希望得到最大的区别,然后是与之相伴的路线。这个查询给了我正确的区别,但不是与它一起使用的id和总数。一位同事也建议按ID分组,但正如我所认为的那样,只是将结果放平,并且每个ID都列出来,而不是一天中具有最大差异的一个ID。

感谢很多提前

+0

什么数据库和版本? – RedFilter 2010-01-12 14:38:07

+0

不应该也是你的结果? – RedFilter 2010-01-12 14:39:37

+0

mysql Ver 14.14 Distrib 5.1.39,用于Win32(ia32) – 2010-01-12 14:40:50

回答

1

这一个应该为你工作。

它按降序对总和进行排序,给它们分配一个等级,然后只得到rank = 1的那些。以下查询

SELECT id, `date`, sums FROM (
    SELECT id, `date`, sums, 
    CASE 
    WHEN @d != `date` THEN @rownum := 1 
    ELSE @rownum := @rownum + 1 
    END AS rank, 
    @d := `date` 
FROM 
(
    SELECT t1.`date`, t1.id, t1.sums t1_sums, t2.sums t2_sums, (t1.sums - t2.sums) sums 
    FROM 
    (select `date`, id, sum(val) sums 
    from foo 
    group by `date`, id) as t1, 
    (select `date`, id, sum(val) sums 
    from bar 
    group by `date`, id) as t2, 
    (SELECT @rownum := 0, @d := NULL) r 
    WHERE t1.`date` = t2.`date` AND t1.id = t2.id 
    GROUP BY t1.`date`, t1.id, t2.`date`, t2.id 
    ORDER BY t1.`date`, (t1.sums - t2.sums) DESC, t1.id 
) x 
) y 
WHERE rank = 1 
+0

非常感谢您的帮助! – 2010-01-12 15:44:36

1
SELECT t1.`date`, t1.id, t1.sums, t2.sums, max(t1.sums - t2.sums) FROM 
    (select `date`, id, sum(val) sums 
    from test.foo 
    group by `date`, id) as t1, 
    (select `date`, id, sum(val) sums 
    from test.bar 
    group by `date`, id) as t2 
WHERE t1.`date` = t2.`date` AND t1.id = t2.id 
group by t1.`date` 

在你的日期,但不是ID分组外部查询,因此你没有得到您所期望的ID。如果您想查找与最高差异相关的ID,那么首先您需要找到最高的差异性,然后使用另一个查询来确定哪些ID(或多个ID)与此相关联。你必须决定你想要做什么与重复。像这样的东西(未经测试)...

SELECT t3.`date`, t3.id, t3.diff 
    (SELECT t1.`date`, t1.id, t1.sums, t2.sums, max(t1.sums - t2.sums) as diff FROM 
    (select `date`, id, sum(val) sums 
    from test.foo 
    group by `date`, id) as t1, 
    (select `date`, id, sum(val) sums 
    from test.bar 
    group by `date`, id) as t2 
    WHERE t1.`date` = t2.`date` AND t1.id = t2.id) as t3 
WHERE t3.diff = (correlated subquery to get maximum value of diff for each date) 

或使用单独的查询。

+0

这两个行都返回id'1'。 – 2010-01-12 15:07:22

0

输出是:

+----------+- ---+------+------+-------+ 
|date  |id |sumf |sumb |maxdiff| 
+----------+- ---+------+------+-------+ 
|2010-01-10| 1| 30| 20|  10| 
|2010-01-10| 2| 40| 20|  20| 
|2010-01-10| 3| 60| 20|  40| 
|2010-01-11| 1| 20| 40|  20| 
|2010-01-11| 2| 20| 20|  0| 
|2010-01-11| 3| 20| 20|  0| 
+----------+- ---+------+------+-------+ 


select m.date, m.id, s.sumf, s.sumb, m.maxdiff 
from (
    --subquery2: get the maximum different absolute sum between foo and bar for each date/id combination 
    select s.date, s.id, max(abs(s.sumf - s.sumb)) as maxdiff 
    from (
     --subquery1: get the sum of values for each date/id combination 
     select f.date, f.id, sum(f.val) as sumf, sum(b.val) as sumb 
     from foo f 
     inner join bar b on f.date = b.date and f.id = b.id 
     group by f.date, f.id 
    ) s 
    group by s.date, s.id 
) m 
--join back against subquery1 to find out which sums gave us the max difference 
inner join (
    select f.date, f.id, sum(f.val) as sumf, sum(b.val) as sumb 
    from foo f 
    inner join bar b on f.date = b.date and f.id = b.id 
    group by f.date, f.id 
) s on m.date = s.date and m.id = s.id and m.maxdiff = abs(s.sumf - s.sumb) 

注:这将在被减去标的金额重复maxdiff S的情况下返回多行有不同的值。如果您必须返回sumfsumb,我相信这是正确的行为,否则您不一定会获得创建maxdiff的值。

+0

没有尝试过,但我想如果它们共享相同的max-diff,它会在每个日期返回多行记录?由于这种情况下的行为没有定义,我很好奇,如果这是OP的意图:) – 2010-01-12 15:20:23

+0

我更新了查询的输出。 – RedFilter 2010-01-12 15:22:05

+0

谢谢!这显然是一个例子,将其转化为“真实”问题可能需要一些时间。唯一的原因是我没有把它标记为答案。毕竟,这是一个直接的查询,而答案使用那些脏变量...... :) – 2010-01-12 15:42:55

相关问题