我的表格foobar
包含以下列:
val: tinyint NOT NULL
date: timestamp NOT NULL
type: enum('A', 'B', 'C') NOT NULL
extra: tinyint NOT NULL
对于每个type
,我希望找到与列上的任意条件匹配的行(例如extra > 12 AND val > 0
),最小化val
,并且在{{1}的情况下{{1}最小化val
。我假设对于每个date
这样的行存在并且是唯一的。最后,我希望type
,type
排序结果(与不同的val
值一样多的行)。
如果date
包含以下行:
foobar
查询应返回:
+------+---------------------+------+-------+
| val | date | type | extra |
+------+---------------------+------+-------+
| -1 | 2014-04-10 00:00:00 | A | 40 |
| 1 | 2014-04-15 00:00:00 | A | 15 |
| 2 | 2014-04-12 00:00:00 | A | 77 |
| 1 | 2014-04-11 00:00:00 | A | 2 |
| 1 | 2014-04-14 00:00:00 | A | 22 |
| 1 | 2014-04-10 00:00:00 | B | 40 |
| 1 | 2014-04-15 00:00:00 | B | 15 |
| 1 | 2014-04-12 00:00:00 | B | 77 |
| 1 | 2014-04-11 00:00:00 | B | 2 |
| 1 | 2014-04-14 00:00:00 | B | 22 |
| 4 | 2014-04-10 00:00:00 | C | 40 |
| 3 | 2014-04-15 00:00:00 | C | 15 |
| 3 | 2014-04-12 00:00:00 | C | 77 |
| 1 | 2014-04-11 00:00:00 | C | 2 |
| 3 | 2014-04-14 00:00:00 | C | 22 |
+------+---------------------+------+-------+
这似乎有效:
+------+---------------------+------+-------+
| val | date | type | extra |
+------+---------------------+------+-------+
| 1 | 2014-04-10 00:00:00 | B | 40 |
| 1 | 2014-04-14 00:00:00 | A | 22 |
| 3 | 2014-04-12 00:00:00 | C | 77 |
+------+---------------------+------+-------+
但我发现它过于复杂,我怀疑必须有更好的方法。此外,在单个数值(SELECT a.* FROM (
SELECT MIN(val * 4294967296 + UNIX_TIMESTAMP(date)) AS score
FROM foobar WHERE extra > 12 AND val > 0
GROUP BY type
) AS b
INNER JOIN foobar AS a
ON a.val * 4294967296 + UNIX_TIMESTAMP(a.date) = b.score
ORDER BY val, date;
)中转换我的多列标准适用于这种简单的情况,但在更复杂的情况下可能更难。
是否有其他更通用的方案可以做同样的事情?
答案 0 :(得分:1)
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(val INT SIGNED NOT NULL
,date TIMESTAMP NOT NULL
,type CHAR(1) NOT NULL
,extra TINYINT NOT NULL
,PRIMARY KEY(val,date,type)
);
INSERT INTO my_table VALUES
(-1,'2014-04-10 00:00:00','A',40),
( 1,'2014-04-15 00:00:00','A',15),
( 2,'2014-04-12 00:00:00','A',77),
( 1,'2014-04-11 00:00:00','A', 2),
( 1,'2014-04-14 00:00:00','A',22),
( 1,'2014-04-10 00:00:00','B',40),
( 1,'2014-04-15 00:00:00','B',15),
( 1,'2014-04-12 00:00:00','B',77),
( 1,'2014-04-11 00:00:00','B', 2),
( 1,'2014-04-14 00:00:00','B',22),
( 4,'2014-04-10 00:00:00','C',40),
( 3,'2014-04-15 00:00:00','C',15),
( 3,'2014-04-12 00:00:00','C',77),
( 1,'2014-04-11 00:00:00','C', 2),
( 3,'2014-04-14 00:00:00','C',22);
SELECT a.*
FROM my_table a
JOIN
( SELECT x.val
, x.type
, MIN(x.date) date
FROM my_table x
JOIN
( SELECT MIN(val) val
, type
FROM my_table
WHERE extra > 12
AND val > 0
GROUP
BY type
) y
ON y.type = x.type
AND y.val = x.val
WHERE x.extra > 12
GROUP
BY val
, type
) b
ON b.val = a.val
AND b.type = a.type
AND b.date = a.date;
+-----+---------------------+------+-------+
| val | date | type | extra |
+-----+---------------------+------+-------+
| 1 | 2014-04-14 00:00:00 | A | 22 |
| 1 | 2014-04-10 00:00:00 | B | 40 |
| 3 | 2014-04-12 00:00:00 | C | 77 |
+-----+---------------------+------+-------+