Попытка использовать технику из https://stackoverflow.com/a/123481 я пытаюсь извлечь одну строки для каждого name
, с определенным видом, а именно верхним / первый ряд после сортировки в порядке убывания active
, created
, то prid
. Однако active
столбец может содержать числовые NULL
значения или значения, которые вызывают дубликат в этом name=bat
случае. Любая помощь будет принята с благодарностью.
Исходная таблица:
+------+-------+--------+---------+
| prid | name | active | created |
+------+-------+--------+---------+
| 1 | bat | NULL | 3 |
| 2 | bat | 1 | 2 |
| 3 | bat | 2 | 1 |
| 4 | bat | 3 | 0 |
| 5 | noise | NULL | 2 |
| 6 | noise | NULL | 1 |
| 7 | cup | NULL | 0 |
| 8 | cup | NULL | 0 |
| 9 | egg | 4 | 4 |
| 10 | egg | 4 | 2 |
+------+-------+--------+---------+
Желаемый результат:
+------+-------+--------+---------+
| prid | name | active | created |
+------+-------+--------+---------+
| 9 | egg | 4 | 4 |
| 4 | bat | 3 | 0 |
| 5 | noise | NULL | 2 |
| 8 | cup | NULL | 0 |
+------+-------+--------+---------+
SQL:
SELECT p1.*
FROM source_table p1
LEFT JOIN source_table p2 ON (
p1.name = p2.name
AND (
p1.active < p2.active
OR (
(p1.active = p2.active OR (p1.active IS NULL AND p2.active IS NULL))
AND (
p1.created < p2.created
OR (
p1.created = p2.created AND p1.prid < p2.prid
)
)
)
)
)
WHERE p2.prid IS NULL
ORDER BY p1.active DESC, p1.created DESC, p1.prid DESC
Фактический результат:
+------+-------+--------+---------+
| prid | name | active | created |
+------+-------+--------+---------+
| 9 | egg | 4 | 4 |
| 4 | bat | 3 | 0 |
| 1 | bat | NULL | 3 |
| 5 | noise | NULL | 2 |
| 8 | cup | NULL | 0 |
+------+-------+--------+---------+
@Gordon Linoff
Спасибо за помощь, я пытаюсь использовать вторую версию с индексами (name, active, created, prid)
и (active, created, prid)
, тем не менее, это довольно медленно.
Это занимает 1 секунду, возвращает правильные результаты, но в неправильном порядке:
SELECT t1.prid
FROM source_table t1
WHERE t1.prid = (
SELECT t2.prid
FROM source_table t2
WHERE t2.name = t1.name
ORDER BY t2.active DESC, t2.created DESC, t2.prid DESC
LIMIT 1
)
LIMIT 50
И это занимает 55 секунд:
SELECT t1.prid
FROM source_table t1
WHERE t1.prid = (
SELECT t2.prid
FROM source_table t2
WHERE t2.name = t1.name
ORDER BY t2.active DESC, t2.created DESC, t2.prid DESC
LIMIT 1
)
ORDER BY t1.active DESC, t1.created DESC, t1.prid DESC
LIMIT 50
И действительно мне нужны LIMIT 500
какие-то идеи?
@Rick James
Ссылка SQL Fiddle: http://sqlfiddle.com/#!9/f9b39/2/0