【问题标题】:SQL using N-1 Dense Rank to filter out rows in dense rank N MysqlSQL使用N-1 Dense Rank过滤掉密集秩N中的行 Mysql
【发布时间】:2021-11-21 13:29:43
【问题描述】:

如果我的标题不清楚,这里是我所说的一个例子。

假设我有一张如下所示的表格:

+----+------+----+----+---------+-------+---------+-------+
| ID | Time | X  | Y  | X_START | X_END | Y_START | Y_END |
+----+------+----+----+---------+-------+---------+-------+
|  1 |    0 |  8 |  6 |       6 |    10 |       4 |     8 |
|  2 |    0 | 20 | 10 |      18 |    22 |       8 |    12 |
|  3 |    1 |  8 |  8 |       6 |    10 |       6 |    10 |
|  4 |    1 | 10 | 24 |       8 |    12 |      22 |    26 |
+----+------+----+----+---------+-------+---------+-------+

如果我将此查询应用于表:

WITH 
cte1 AS (SELECT *,
    DENSE_RANK() OVER (ORDER BY TIME) AS DENSE_RANK
    FROM data
    ORDER BY TIME)

SELECT * FROM cte1

我明白了:

+----+------+----+----+---------+-------+---------+-------+------------+
| ID | Time | X  | Y  | X_START | X_END | Y_START | Y_END | DENSE_RANK |
+----+------+----+----+---------+-------+---------+-------+------------+
|  1 |    0 |  8 |  6 |       6 |    10 |       4 |     8 |          1 |
|  2 |    0 | 20 | 10 |      18 |    22 |       8 |    12 |          1 |
|  3 |    1 |  8 |  8 |       6 |    10 |       6 |    10 |          2 |
|  4 |    1 | 10 | 24 |       8 |    12 |      22 |    26 |          2 |
+----+------+----+----+---------+-------+---------+-------+------------+

现在我要做的是过滤掉 X 在 X_START - X_END 范围内且 Y 在 Y_START - Y_END 范围内且 DENSE_RANK 为 n-1 的任何行

所以我想要一个看起来像这样的结果:

+----+------+----+----+---------+-------+---------+-------+------------+
| ID | Time | X  | Y  | X_START | X_END | Y_START | Y_END | DENSE_RANK |
+----+------+----+----+---------+-------+---------+-------+------------+
|  1 |    0 |  8 |  6 |       6 |    10 |       4 |     8 |          1 |
|  2 |    0 | 20 | 10 |      18 |    22 |       8 |    12 |          1 |
|  4 |    1 | 10 | 24 |       8 |    12 |      22 |    26 |          2 |
+----+------+----+----+---------+-------+---------+-------+------------+

我对 SQL 很陌生,所以我不太确定如何去做。提前感谢您的所有帮助!

【问题讨论】:

  • 什么是n?...
  • n 只是任何dense_rank 值,所以我总是想查看prev dense_rank val
  • 为什么将结果的 3d 行视为dense_rank=2 的第一个?由于您的 ORDER BY 子句仅按时间排序,因此该行被任意选择为第 1 个 dense_rank=2。
  • 还有一个名为 ID 的列(它是主键),我认为它只是按此排序。如果它很重要,我可以在那里添加它

标签: mysql sql mariadb window-functions


【解决方案1】:

使用MIN() 窗口函数确定每个Time 的最小ID,以便在所有其他条件也都满足的情况下排除该行:

WITH cte AS (
    SELECT *, 
           DENSE_RANK() OVER (ORDER BY TIME) AS `DENSE_RANK`,
           MIN(ID) OVER (PARTITION BY TIME) min_id
    FROM data
  )
SELECT ID, Time, X, Y, X_START, X_END, Y_START, Y_END, `DENSE_RANK` 
FROM cte
WHERE `DENSE_RANK` = 1 
  OR NOT (ID = min_id AND X BETWEEN X_START AND X_END AND Y BETWEEN Y_START AND Y_END)
ORDER BY `DENSE_RANK`, ID;

请参阅demo。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-14
    • 2023-03-24
    • 2013-06-11
    • 2021-02-12
    相关资源
    最近更新 更多