这是一个我有一个工作查询的问题,但它对我来说感觉非常低效,我想帮助构建一个更好的问题。这将进入实时生产环境,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行的表上。再次,效率是关键。
答案 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 |
+----+------------+------------+