想象一下,我有一个名为 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相同,则订单将有所不同。按ID排序,行的顺序为4、5和6,但按消息的顺序为4、6和5。
这是我的问题,是否可以通过查询来了解哪个item_ids
与两个查询相比具有不同的顺序?
在此示例中,结果将是项目2和3。
答案 0 :(得分:2)
如果我理解正确,则可以使用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;
答案 1 :(得分:0)
您可以使用变量来解决此问题,这是一个间隙和孤岛问题。
以下查询:
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;