我有一個包含所有事件 ID 和事件日期的表。對于特定的 eventID 子集,我需要獲取當前日期之后的兩個日期。我已經嘗試了很多次迭代并查看了許多通過 GROUP 回傳前 N 個結果的帖子 - 但我無法讓這些示例中的任何一個作業,因為這些示例沒有像我需要的那樣使用日期。(例如:在 GROUP BY 中使用 LIMIT 以獲得每組 N 個結果?)
------------ -----
| eDate | ID |
------------ -----
| 2021-10-27 | 1 |
------------ -----
| 2021-11-03 | 1 |
------------ -----
| 2021-11-10 | 1 |
------------ -----
| 2021-11-17 | 1 |
------------ -----
| 2021-11-24 | 1 |
------------ -----
| 2021-12-01 | 1 |
------------ -----
| 2021-12-08 | 1 |
------------ -----
| 2021-10-27 | 2 |
------------ -----
| 2021-11-03 | 2 |
------------ -----
| 2021-11-10 | 2 |
------------ -----
| 2021-11-17 | 2 |
------------ -----
| 2021-11-24 | 2 |
------------ -----
| 2021-12-01 | 2 |
------------ -----
| 2021-12-08 | 2 |
------------ -----
| 2021-10-27 | 3 |
------------ -----
| 2021-11-03 | 3 |
------------ -----
| 2021-11-10 | 3 |
------------ -----
| 2021-11-17 | 3 |
------------ -----
| 2021-11-24 | 3 |
------------ -----
| 2021-12-01 | 3 |
------------ -----
| 2021-12-08 | 3 |
------------ -----
SELECT eDate,ID,COUNT(*) as eCount FROM myTable WHERE ID in (1,3) AND eDate >=CURDATE() GROUP BY ID,eDate HAVING eCount < 3 ;
此查詢不起作用,因為它GROUP BY ID,eDate創建了一個唯一的對,因此它回傳 ID 1 和 3 的所有條目 - 所有條目都帶有eCount = 1
從技術上講,我實際上并不需要,eCount但它說明了我為獲得正確結果而進行的眾多嘗試之一。如果今天是 2020 年 10 月 28 日,我想要的結果將如下。
------------ ----- --------
| eDate | ID | eCount |
------------ ----- --------
| 2021-11-03 | 1 | 1 |
------------ ----- --------
| 2021-11-10 | 1 | 2 |
------------ ----- --------
| 2021-11-03 | 3 | 1 |
------------ ----- --------
| 2021-11-10 | 3 | 2 |
------------ ----- --------
uj5u.com熱心網友回復:
我想我想出了一個解決方案......我不知道它的擴展性如何,或者我是否需要考慮其他警告,但我突然想到我不需要使用 GROUP BY 因為我已經在尋找為ID in (1,3)。我需要做的就是計算我要查找的 ID 的數量并將其乘以 2 以設定為LIMIT
IE: 1,3 = LIMIT 4
SELECT * FROM myTable WHERE ID IN (1,3) AND eDate>=CURDATE() ORDER BY eDate LIMIT 4 ;
IE: 1,3,11, 15 = LIMIT 8
SELECT * FROM myTable WHERE ID IN (1,3,11,15) AND eDate>=CURDATE() ORDER BY eDate LIMIT 4 ;
這將獲取這些 ID 的所有日期,按日期排序……所以前 4 名或前 8 名將是我需要的所有記錄。
uj5u.com熱心網友回復:
只有在當前日期之后有 2 個或更多日期時,您的解決方案才有效。觀察這個例子,如果你們中的一個 id 只有 1 個日期出現在當前日期之后,LIMIT 4在這個查詢中:
SELECT * FROM myTable WHERE ID IN (1,3) AND eDate>=CURDATE() ORDER BY eDate LIMIT 4 ;
.. 將填充另一行ID=1。結果可能是這樣的:
------------ ----
| eDate | ID |
------------ ----
| 2021-11-03 | 3 |
| 2021-11-03 | 1 |
| 2021-11-10 | 1 |
| 2021-11-17 | 1 |
------------ ----
我猜這不是你想要的。
按照 Akina 對"Use ROW_NUMBER() in CTE"的評論,如果您使用的是支持視窗函式的 MySQL 版本,這可能是您需要的查詢:
WITH cte AS (
SELECT eDate, ID, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY eDate) eCount
FROM myTable WHERE eDate>=CURDATE()
ORDER BY ID, eDate)
SELECT * FROM cte
WHERE eCount <=2;
您將獲得出現在當前日期之后的所有 ID 日期記錄,并且可以靈活地定義或不定義特定 ID,而無需使用LIMIT. 對于不支持視窗函式的舊 MySQL 版本,您可能可以模仿使用行號的相同想法,如下所示:
SELECT eDate, ID, rownum
FROM
( SELECT *,
@rn:=CASE WHEN @i = ID AND eDate >= CURDATE()
THEN @rn 1
ELSE 0 END AS rownum,
@i := ID
FROM myTable m
CROSS JOIN (SELECT @i:=0, @rn:=0) r
ORDER BY ID, eDate) v
WHERE rownum > 0 AND rownum <= 2
ORDER BY ID, eDate;
演示小提琴
uj5u.com熱心網友回復:
您沒有指定 eDate 的型別,所以如果 eDate 型別是 DATE(只有日期沒有時間),我希望這可以幫助您。
SELECT eDate, ID, COUNT(ID) AS eCount
FROM myTable
WHERE ID IN (1,3) -- This condition return just two ids (1 and 3)
AND eDate BETWEEN CONVERT(DATE, GETDATE()) AND CONVERT(DATE, DATEADD(DAY, 2, GETDATE())) -- This condition return the next two dates, beyond the current date ( current date = GETDATE() )
GROUP BY ID, eDate
HAVING eCount < 3 -- This condition ensure select rows just have count loser than 3;
但如果 eDate 型別是 DATETIME,則必須先將其轉換。 CONVERT(DATE, eDate)
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/341353.html
