Внизу имеется версия TLDR.
Примечание. Мое текущее решение основано на предложенном решении в здесь, в этом вопросе (предложенном в самом тексте вопроса) , однако это не работает для меня, даже если это работает для этого человека. Так что я не уверен, как с этим справиться, потому что вопрос кажется дубликатом, но ответ, который там дан, не работает для меня. Поэтому я думаю, что-то должно быть по-другому для меня. Если кто-то может сказать мне, как правильно с этим справиться, я открыт для слушания.
У меня есть такая таблица:
scope_id key_id value
0 0 0_0
0 1 0_1
1 0 1_0
2 0 2_0
2 1 2_1
Области имеют иерархию, где область действия 0 является родителем области 2, а область 2 является родителем области 1. (с целью не отсортированы, их идентификаторы являются UUID, только для чтения чисел здесь)
Мой вариант использования заключается в том, что я хочу получить значение множественного ключи в определенной c области (область 1). Однако, если для области 1 не определено значение, я подойдет со значением его родителя (область 2) и, наконец, если в области 2 также нет значения, я бы взял значение из его родителя, область 0. Поэтому, если возможно, я хочу получить значение из области 1, если оно не имеет значения, то из области 2 и, наконец, я пытаюсь получить значение из области 0. (Области являются древовидной структурой, поэтому каждая область может иметь не более одного родителя). Однако родитель может иметь несколько дочерних элементов.)
Так что в приведенном выше примере, если я хочу получить значение ключа 0 в области 1, я хотел бы получить 1_0
, поскольку ключ определен в объем. Если я хочу получить значение ключа 1 в области видимости 1, я хотел бы получить 2_1
, поскольку в области действия 1 не определено значение, но в родительской области действия 2 оно есть. И, наконец, если я хочу получить значения ключей 0 и 1 в области видимости 1, я хочу получить 1_0
и 2_1
.
В настоящее время это решается путем создания 3 отдельных SQL запросов и объединения их в код. Это работает хорошо и достаточно быстро, но я хочу посмотреть, будет ли это быстрее с одним запросом SQL. Я предложил следующий запрос (на основе обновления в тексте вопроса здесь ):
SELECT *
FROM (
SELECT *
FROM test
WHERE key_id IN (0, 1)
AND scope_id IN (1 , 2, 0)
ORDER BY FIELD(scope_id, 1 , 2, 0)
) t1
GROUP BY t1.key_id;
Внутренний подзапрос сначала находит все ключи, на которые я хочу посмотреть, и проверяет, они находятся в области, которую я хочу посмотреть, или в родительской области. Затем я заказываю прицелы, чтобы сначала был ребенок, потом родитель, потом дедушка. Теперь я ожидаю, что group by оставит значение первой найденной строки, так что, надеюсь, дочерний элемент (область 1). Однако это не работает. Вместо этого используется первое значение, основанное на фактической таблице.
TLDR
При группировании с GROUP BY
в запросе выше, почему порядок, определенный запросом ORDER BY
, игнорируется? Вместо этого при группировании берется первое значение, основанное на исходной таблице.
Используя этот код, вы можете попробовать сами:
# this group by doesn't work with strict mode
SET sql_mode = '';
CREATE TABLE IF NOT EXISTS test(
scope_id int,
key_id int,
`value` varchar(20),
PRIMARY KEY (scope_id, key_id)
);
INSERT IGNORE INTO test values
(0, 0, "0_0"),
(1, 0, "1_0"),
(2, 0, "2_0"),
(2, 1, "2_1"),
(0, 1, "0_1");
SELECT *
FROM (
SELECT *
FROM test
WHERE key_id IN (0, 1)
AND scope_id IN (1 , 2, 0)
ORDER BY FIELD(scope_id, 1 , 2, 0)
) t1
GROUP BY t1.key_id;
# expected result are the rows that contain value 1_0 and 2_1