【发布时间】:2014-10-14 21:59:53
【问题描述】:
我需要对 MySQL 数据库进行一个非常具体的查询,我将从表示例开始:
+----+---------------+------------------------------------+----------+
| id | data | pattern_key | hash |
+----+---------------+------------------------------------+----------+
| 1 | {"user":true} | NOTIFICATIONHUB::SYSTEM | ABCDEFGH |
| 2 | {"user":true} | NOTIFICATIONHUB::SYSTEM | ABCDEFGH |
| 3 | {"user":true} | NOTIFICATIONHUB::SYSTEM | ABCDEFGH |
| 4 | {"user":true} | NOTIFICATIONHUB::SYSTEM | HGFEDCBA |
| 5 | {"user":true} | NOTIFICATIONHUB::SYSTEM | HGFEDCBA |
| 6 | {"user":true} | NOTIFICATIONHUB::SYSTEM | OPQRSTUW |
| 7 | {"user":true} | NOTIFICATIONHUB::SYSTEM | ABCDEFGH |
| 8 | {"user":true} | NOTIFICATIONHUB::SYSTEM | ABCDEFGH |
| 9 | {"user":true} | NOTIFICATIONHUB::SYSTEM | IJKLMNOP |
| 10 | {"user":true} | NOTIFICATIONHUB::SYSTEM | ABCDEFGH |
+----+---------------+------------------------------------+----------+
如您所见,我有列 data 和 pattern_key,此时它们无关紧要。重要的是哈希列,它允许相同的值,即:ABCDEFGH。我想要做的是选择按 ID 降序排列的 5 行,但包括哈希列上的重复项,并且仅当它们彼此之后。该表的查询结果应该是:
+----+---------------+------------------------------------+----------+
| id | data | pattern_key | hash |
+----+---------------+------------------------------------+----------+
| 10 | {"user":true} | NOTIFICATIONHUB::SYSTEM | ABCDEFGH |
| 9 | {"user":true} | NOTIFICATIONHUB::SYSTEM | IJKLMNOP |
| 8 | {"user":true} | NOTIFICATIONHUB::SYSTEM | ABCDEFGH |
| 7 | {"user":true} | NOTIFICATIONHUB::SYSTEM | ABCDEFGH |
| 6 | {"user":true} | NOTIFICATIONHUB::SYSTEM | OPQRSTUW |
| 5 | {"user":true} | NOTIFICATIONHUB::SYSTEM | HGFEDCBA |
+----+---------------+------------------------------------+----------+
我们有 6 条记录,不是限制为 5 条,但包含第 7 行,因为第 8 行具有相同的哈希值。这种行为必须忽略重复的数量,只要它们一个接一个,所以如果我们按 id 升序排序,我们会得到:
+----+---------------+------------------------------------+----------+
| id | data | pattern_key | hash |
+----+---------------+------------------------------------+----------+
| 1 | {"user":true} | NOTIFICATIONHUB::SYSTEM | ABCDEFGH |
| 2 | {"user":true} | NOTIFICATIONHUB::SYSTEM | ABCDEFGH |
| 3 | {"user":true} | NOTIFICATIONHUB::SYSTEM | ABCDEFGH |
| 4 | {"user":true} | NOTIFICATIONHUB::SYSTEM | HGFEDCBA |
| 5 | {"user":true} | NOTIFICATIONHUB::SYSTEM | HGFEDCBA |
| 6 | {"user":true} | NOTIFICATIONHUB::SYSTEM | OPQRSTUW |
| 7 | {"user":true} | NOTIFICATIONHUB::SYSTEM | ABCDEFGH |
| 8 | {"user":true} | NOTIFICATIONHUB::SYSTEM | ABCDEFGH |
| 9 | {"user":true} | NOTIFICATIONHUB::SYSTEM | IJKLMNOP |
+----+---------------+------------------------------------+----------+
因为我们有 3 个 ABCDEFGH(我认为是 1 个唯一的元行)、2 个 HGFEDCBA(2 个唯一的元行)、1 个 OPQRSTUW(第 3 个唯一的行)、2 个 ABCDEFGH(4 个唯一的元行,因为它们是从前 3 个 ABCDEFGH 与其他哈希)和一个 IJKLMNOP。
我在考虑 group by,但它会裁剪重复项,我希望将它们包含在数据集中。有什么想法吗?
感谢@Uueerdo,我想出了那个解决方案(是的,无论如何都需要加入):
SET @i := 0;
SET @lastHash := '';
SELECT *
FROM
(SELECT notification_real_id AS id, data, pattern_key, @i := IF(hash <> @lastHash, @i + 1, @i) AS hashGroup, @lastHash := hash AS hash
FROM
( SELECT notifications.id AS notification_real_id,
data,
pattern_key,
hash
FROM notifications
INNER JOIN notifications_users ON notifications.id = notifications_users.notification_id
WHERE notifications_users.user_id = 1) AS subJoin
ORDER BY notification_real_id DESC) AS subQ
WHERE hashGroup <= 5;
【问题讨论】:
-
那么,换个说法,你想
LIMIT查询结果的unique 散列数吗?例如,您最多需要 5 个不同的哈希值,但可能是 5 行,也可能是 8 行……对吗? -
是的!我想选择 UNTIL 5 个不同的散列,但问题是它们可以重复(所以不是真正不同),只要它们与先前的“相同散列”组与另一行和另一个散列分开。
-
存储过程就足够了吗?
-
如果这是mysql,你可以按hash分组,按id desc排序并选择max(id),然后限制5。mysql没有与mssql相同的检查,这不会与合作
-
我不想使用存储过程,因为它是 CMS 系统插件的一部分,我不想处理存储过程的添加和删除。
标签: mysql