MySQL - Как я могу сравнить, если порядок результата запроса такой же, как у другого? - PullRequest
0 голосов
/ 05 июля 2018

Представьте, что у меня есть таблица базы данных с именем Log , и она выглядит так:

+----+---------+---------+
| id | item_id | message |
+----+---------+---------+
| 1  |    1    |    A    |
+----+---------+---------+
| 2  |    1    |    B    |
+----+---------+---------+
| 3  |    1    |    C    |
+----+---------+---------+
| 4  |    2    |    A    |
+----+---------+---------+
| 5  |    2    |    C    |
+----+---------+---------+
| 6  |    2    |    B    |
+----+---------+---------+
| 7  |    3    |    B    |
+----+---------+---------+
| 8  |    3    |    A    |
+----+---------+---------+
| 9  |    3    |    C    |
+----+---------+---------+

Если я сделаю запрос

select * from log where item_id = 1 order by id;

Я получу строки 1, 2 и 3. То же самое, что если я сделаю запрос

select * from log where item_id = 1 order by message;

Но если я сделаю то же самое с пунктом 2, заказы будут другими. При сортировке по идентификатору порядок строк будет 4, 5 и 6, но по сообщениям - 4, 6 и 5.

Итак, вот мой вопрос: можно ли сделать запрос, чтобы узнать, какие item_ids имеют разные порядки, сравнивая два запроса?

В этом примере результатом будут пункты 2 и 3.

Ответы [ 2 ]

0 голосов
/ 05 июля 2018

Если я правильно понимаю, вы можете использовать group_concat():

select l.item_id,
       group_concat(l.id order by l.id) as id_ordering,
       group_concat(l.id order by l.message) as message_ordering
from log l
group by l.item_id;

Вы можете получить те, которые отличаются, используя предложение having:

select l.item_id,
       group_concat(l.id order by l.id) as id_ordering,
       group_concat(l.id order by l.message) as message_ordering
from log l
group by l.item_id
having id_ordering <> message_ordering;
0 голосов
/ 05 июля 2018

Вы можете использовать переменные, чтобы решить эту проблему как проблему пробелов и островков .

Следующий запрос:

SELECT id, item_id, message, id - seq
FROM (
  SELECT id, item_id, message,
         @seq := IF(@i = item_id, @seq + 1, 
                    IF(@i := item_id, 1, 1)) AS seq       
  FROM log
  CROSS JOIN (SELECT @i := 0, @seq := 0) AS v
  ORDER BY item_id, message) AS t
ORDER BY id;

генерирует этот вывод:

id, item_id, message, id - seq
--------------------------------
1,  1,       A,       0
2,  1,       B,       0
3,  1,       C,       0
4,  2,       A,       3
5,  2,       C,       2
6,  2,       B,       4
7,  3,       B,       5
8,  3,       A,       7
9,  3,       C,       6

Таким образом, id-seq может использоваться для обнаружения несоответствий порядка между id и message:

SELECT item_id
FROM (
  SELECT id, item_id, message,
         @seq := IF(@i = item_id, @seq + 1, 
                    IF(@i := item_id, 1, 1)) AS seq       
  FROM log
  CROSS JOIN (SELECT @i := 0, @seq := 0) AS v
  ORDER BY item_id, message) AS t
GROUP BY item_id
HAVING COUNT(DISTINCT id-seq) > 1  
ORDER BY id;

Демо здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...