从分组行中的同一列中获取特定值

时间:2014-01-13 21:11:35

标签: mysql group-by

这是一个我有一个工作查询的问题,但它对我来说感觉非常低效,我想帮助构建一个更好的问题。这将进入实时生产环境,db每天处理的查询数量非常高,因此效率越高越好。我有一个像这样的表格(仅剥离相关部分):

id | type | datecolumn
1  | A    | 2014-01-01
1  | B    | 0000-00-00
2  | A    | 2014-01-02
2  | B    | 2014-01-10
3  | A    | 2014-01-01
3  | B    | 0000-00-00

每个id总会有两行,一个是A类,一个是B类.A将始终有一个有效日期,B将有一个日期> = A或全0。我想要的是一个产生类似于此的输出的查询:

id | date for A | date for B
1  | 2014-01-01 | None
2  | 2014-01-02 | 2014-01-10
3  | 2014-01-01 | None

我现在这样做的方式如下:

SELECT
    id,
    IF(MIN(datecolumn) > 0, MIN(datecolumn), MAX(datecolumn)) AS 'date for A',
    IF(MIN(datecolumn) > 0, MAX(datecolumn), 'None') AS 'date for B'
GROUP BY id

但是我觉得我应该能够以某种方式在by-type基础上获取datecolumn值。我知道最简单的解决方案应该是更改表结构,以便每个id只使用一行,但我担心在这种情况下不可能;必须有两行。有没有办法在此查询中正确利用类型列?

编辑:此外,这是在一个超过10,000,000行的表上。再次,效率是关键。

2 个答案:

答案 0 :(得分:0)

确保您有一个涵盖id和type列的索引(例如ALTER TABLE tbl ADD INDEX (type,id)),然后执行:

SELECT
    table_a.id,
    table_a.datecolumn AS 'date for A',
    IF(table_b.datecolumn > 0, table_b.datecolumn, 'None') AS 'date for B'
FROM tbl AS table_a
JOIN tbl AS table_b ON table_a.id = table_b.id AND table_b.type = 'B'
WHERE table_a.type = 'A';

答案 1 :(得分:0)

我会坚持你的目标,但也许这样写吧......

CREATE TABLE my_table
(id INT NOT NULL
,type CHAR(1) NOT NULL
,datecolumn DATE NOT NULL DEFAULT '0000-00-00'
,PRIMARY KEY(id,type)
);

INSERT INTO my_table VALUES
(1  ,'A','2014-01-01'),
(1  ,'B','0000-00-00'),
(2  ,'A','2014-01-02'),
(2  ,'B','2014-01-10'),
(3  ,'A','2014-01-01'),
(3  ,'B','0000-00-00');

 SELECT id
      , MAX(CASE WHEN type = 'A' THEN datecolumn END) a
      , MAX(REPLACE(CASE WHEN type='B' THEN datecolumn END,'0000-00-00','none')) b 
   FROM my_table 
  GROUP 
     BY id;
+----+------------+------------+
| id | a          | b          |
+----+------------+------------+
|  1 | 2014-01-01 | none       |
|  2 | 2014-01-02 | 2014-01-10 |
|  3 | 2014-01-01 | none       |
+----+------------+------------+