Có cách nào để tạo ngày giữa các phạm vi ngày. Sau khi nhìn vào để tôi phát hiện ra có một cách để sử dụng CTE, một tùy chọn khác là sử dụng tất cả liên minh từ 0 đến 9. Có chức năng sẵn có mà tôi có thể sử dụng để tạo ngày giữa phạm vi ngày không?
Chúng tôi đang sử dụng MySQL 8.0.
Hỏi ngày 5 tháng 12 năm 2018 lúc 9:28Dec 5, 2018 at 9:28
3
Tôi đã thử giải pháp này:
WITH recursive Date_Ranges AS [
select '2018-11-30' as Date
union all
select Date + interval 1 day
from Date_Ranges
where Date < '2018-12-31']
select * from Date_Ranges;
Kondybas
4.18414 Huy hiệu bạc13 Huy hiệu đồng14 silver badges13 bronze badges
Đã trả lời ngày 6 tháng 12 năm 2018 lúc 10:07Dec 6, 2018 at 10:07
Nó thường hữu ích khi có một loạt các ngày tiếp giáp khi xây dựng các truy vấn SQL, ví dụ bằng cách sử dụng tham gia bên trái để đảm bảo rằng dữ liệu từ các bảng khác có thể có ngày bị thiếu sẽ nhận được giá trị null trong các hàng đó thay vì bỏ qua các hàng hoàn toàn.
Postgres có chức năng Generate_series tuyệt vời của nó có thể giải quyết rất nhiều vấn đề này. Thật không may, MySQL không có chức năng tương tự.
Bạn có thể tạo ra một loạt các ngày tiếp giáp trong MySQL với một truy vấn như thế này:
SELECT date_series.dates
FROM [
SELECT curdate[] - INTERVAL [units.mul + [10 * tens.mul] + [100 * hundreds.mul] + [1000 * thousands.mul]] DAY AS dates
FROM [SELECT 0 AS mul UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9] AS units
CROSS JOIN [SELECT 0 AS mul UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9] AS tens
CROSS JOIN [SELECT 0 AS mul UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9] AS hundreds
CROSS JOIN [SELECT 0 AS mul UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9] AS thousands
] date_series
Điều đó sẽ tạo ra 10000 ngày như thế này:
+----------+
|dates |
+----------+
|2021-08-23|
|2021-08-22|
|2021-08-21|
|2021-08-20|
|2021-08-19|
|2021-08-18|
|2021-08-17|
|2021-08-16|
|2021-08-15|
|2021-08-14|
| ... |
+----------+
Điều này có vẻ hơi điên rồ lúc đầu, nhưng nó hợp lý một khi bạn xem qua nó. Nó sử dụng một loạt các kết nối chéo để xây dựng các vị trí thập phân với các giá trị từ 0 đến 9, cho các đơn vị, hàng chục, hàng trăm và hàng ngàn vị trí. Sau đó, nó trừ đi mỗi số kết quả là một số ngày kể từ ngày hiện tại để tạo ra phạm vi ngày tiếp giáp mà chúng tôi muốn.
Truy vấn này sử dụng curdate[] - INTERVAL
để tạo ngày quay ngược thời gian kể từ hôm nay. Bạn có thể trao đổi curdate[]
cho một ngày khác để có một điểm bắt đầu khác hoặc thực hiện + INTERVAL
để tạo ngày đi về phía trước kể từ ngày ban đầu.
Truy vấn này tạo ra một phạm vi 10000 ngày, khoảng 27 năm và có lẽ đủ cho hầu hết các mục đích. Bạn có thể điều chỉnh phạm vi với mệnh đề WHERE
cho phù hợp với các nhu cầu khác nhau, ví dụ:
SELECT a.dates
FROM [
SELECT curdate[] - INTERVAL [units.mul + [10 * tens.mul] + [100 * hundreds.mul] + [1000 * thousands.mul]] DAY AS dates
FROM [SELECT 0 AS mul UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9] AS units
CROSS JOIN [SELECT 0 AS mul UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9] AS tens
CROSS JOIN [SELECT 0 AS mul UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9] AS hundreds
CROSS JOIN [SELECT 0 AS mul UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9] AS thousands
] a
WHERE a.dates >= curdate[] - INTERVAL 1 YEAR
AND DAYNAME[a.dates] = 'Monday'
Điều đó giới hạn phạm vi ngày đến ngày trước một năm và chỉ thứ Hai:
+----------+
|dates |
+----------+
|2021-08-23|
|2021-08-16|
|2021-08-09|
|2021-08-02|
|2021-07-26|
|2021-07-19|
|2021-07-12|
|2021-07-05|
|2021-06-28|
|2021-06-21|
| ... |
+----------+
Nhân tiện, nếu bạn cần trợ giúp với MySQL hoặc SQL trong doanh nghiệp của mình, bạn có thể thuê tôi làm nhà phát triển SQL tự do.
Công nghệ đã đề cập
- Mysql
- SQL