仅对相邻行进行分组

问题描述 投票:0回答:5

嗨,我有一张这样的桌子:

notifies

id,user_id
1,3
2,3
3,4
4,5
5,6
6,3
7,4
8,4
9,3
10,3

我必须创建一个仅对相邻行进行分组的查询

所以,这个例子的结果应该是:

user_id
3
4
5
6
3
4
3

我怎样才能做到这一点? 谢谢

sql mysql
5个回答
5
投票
SELECT  user_id
FROM    notifies n
WHERE   NOT
        (
        SELECT  user_id
        FROM    notifies ni
        WHERE   ni.id < n.id
        ORDER BY
                id DESC
        LIMIT 1
        ) <=> user_id

0
投票
Select N.id, N.user_id
From notifies As N
Where Exists    (
                Select 1
                From notifies As N2
                Where N2.id = N.id + 1
                    And N2.user_id <> N.user_id
                )

0
投票

我认为最好的选择是进行相当简单的选择,将结果放入某些应用程序并以更合适(命令式)的语言对其进行过滤。但是,如果您需要,我的纯 MySQL 版本。您必须按

id
订购数据。

SELECT a.user_id
FROM notifies AS a
LEFT JOIN notifies AS c ON (
    SELECT MIN(id) FROM notifies AS b WHERE b.id > a.id
) = c.id
WHERE a.user_id <> c.user_id OR c.user_id IS NULL
ORDER BY a.id

第二个例子:

SELECT c.user_id
    FROM (
    SELECT a.id, a.user_id, MIN(b.id) AS next
    FROM notifies AS a
    LEFT JOIN notifies AS b ON b.id > a.id
    GROUP BY a.id, a.user_id

) AS c
LEFT JOIN notifies AS d ON d.id = c.next
WHERE c.user_id <> d.user_id OR c.next IS NULL
ORDER BY c.id

0
投票

试试这个:

  1. 选择通知表,并使用 ROW_NUMBER() 命令放置行号,按 id 排序(称为 id_no)
  2. 也使用行号创建子选择查询(称为 prev_id_no),但仅选择上一行(其中 prev_id_no = (id_no - 1))
  3. 将上面的两个 select 语句嵌套在 SELECT * FROM () 下,以便可以操作 row_numbers
  4. 创建一个列来评估 #1 user_id 是否等于 #2 user_id。使用“CASE THEN 'YES ELSE 'NO' AS [DUPLICATE]”
  5. 嵌套 #3 中的最终结果表并按 DUPLICATE = 'NO' 进行过滤

SQL是这样的:

SELECT [user_id] FROM (
    SELECT *,
    CASE WHEN (
        SELECT [user_id] FROM (
            SELECT ROW_NUMBER() OVER(ORDER BY id) AS [prev_id_no], 
            [user_id]

            FROM notifies
        ) FILTER_IN

        WHERE FILTER_IN.prev_id_no = (FILTER_OUT.id_no - 1)
    ) = FILTER_OUT.[user_id] THEN 'YES' ELSE 'NO' END AS [DUPLICATE]

    FROM (
        SELECT ROW_NUMBER() OVER(ORDER BY id) AS [id_no], 
        [user_id]

        FROM notifies
    ) FILTER_OUT
) FILTER_FINAL

WHERE FILTER_FINAL.DUPLICATE = 'NO'

结果是:

user_id
3
4
5
6
3
4
3

0
投票

聚会迟到了,但我想出了:

WITH notifiesgrouped AS (
SELECT id, user_id, 
grp=ROW_NUMBER() OVER (ORDER BY id) - ROW_NUMBER() OVER (PARTITION BY user_ID ORDER BY ID)
FROM notifies)
SELECT USER_ID FROM notifiesgrouped GROUP BY USER_ID, grp ORDER BY MIN(id)

因此,使用 CTE 生成 row_number 并去掉按 id 分区的行号 - 这给出:

id  user_id grp
1   3   0
2   3   0
3   4   2
4   5   3
5   6   4
6   3   3
7   4   5
8   4   5
9   3   5
10  3   5

然后按 userid 和 grp 进行分组 - 按 min(id) 进行排序以保持排序。给予:

USER_ID
3
4
5
6
3
4
3
© www.soinside.com 2019 - 2024. All rights reserved.