我有一個有兩個欄位的表 - id 和 counter。我想按計數器欄位對所有記錄進行排序,然后按其 id 選擇一條記錄,并找出其計數器在整個表中的位置。例如:
| ID | 柜臺 |
|---|---|
| 1 | 1 |
| 2 | 5 |
| 3 | 6 |
| 4 | 0 |
| 5 | 4 |
計數器的 ASC 訂單將是:4, 1, 5, 2, 3.
假設我想獲得 id=2 的位置,我正在尋找的值是 4,因為它在結果集中。
我找到了一些使用 ROW_NUMBER 方法的解決方案,但這些解決方案似乎都適用于整個結果。我只希望通過其 id 為特定行提供一個特定值。
我試圖使用一個更簡單的解決方案,通過在計數器更改時更新表來簡單地將排名存盤在計數器欄位旁邊的表中:
UPDATE mytable
SET counter_rank = ( SELECT COUNT(*)
FROM mytable
WHERE counter >= ( SELECT counter
FROM mytable
WHERE id = ?
GROUP BY counter)
)
WHERE id = ?
這是一個很好的解決方案,但它不起作用,因為如果另一個計數器發生變化,則必須計算所有行的排名,這對我的情況來說不是一個好主意。所以我必須看看行號方法的動態解決方案。
還必須考慮按計數器分組 - 多行可以通過具有相同的計數器值來共享排名中的位置。所以不止一行可以回傳相同的數字/位置。
uj5u.com熱心網友回復:
如果您獲得多行及其等級,我會使用您發現的 ROW_NUMBER,但在子查詢中。然后從該子查詢中選擇所需的行。但是如果你只得到一行,這很容易通過連接計算前幾行來完成:
select mytable.id, mytable.counter, count(t2.id) counter_rank
from mytable
left join mytable t2 on t2.counter < mytable.counter
where mytable.id=2
(如果你想要一個基于 1 的計數器,而不是一個基于 0 的計數器,則添加 1)
小提琴
uj5u.com熱心網友回復:
SELECT id, counter,
ROW_NUMBER() OVER (ORDER BY counter) position
FROM mytable
/* ORDER BY {needed expression} */
;
對于特定行:
WITH cte AS (
SELECT id, counter,
ROW_NUMBER() OVER (ORDER BY counter) position
FROM mytable
)
SELECT * FROM cte WHERE id = {needed value}
;
如果查詢counter不是唯一的,則查詢不是確定性的,在這種情況下您必須擴展排序運算式。例如,直到ORDER BY couner, id。
uj5u.com熱心網友回復:
如果您的 Version hasent 視窗功能,您可以使用這樣的查詢:
SELECT FIND_IN_SET('2', GROUP_CONCAT(id ORDER BY counter)) AS position
FROM pos
ORDER BY counter;
樣本
MariaDB [test]> select * from pos;
---- ---------
| id | counter |
---- ---------
| 1 | 1 |
| 2 | 5 |
| 3 | 6 |
| 4 | 0 |
| 5 | 4 |
---- ---------
5 rows in set (0.000 sec)
MariaDB [test]> SELECT FIND_IN_SET('2', GROUP_CONCAT(id ORDER BY counter)) AS position
-> FROM pos
-> ORDER BY counter;
----------
| position |
----------
| 4 |
----------
1 row in set (0.000 sec)
MariaDB [test]>
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/409066.html
標籤:
