استخراج روزهای موجود در یک بازه تاریخی با SQL
فرض کنید بازه تاریخی بین '2010-01-20' و '2010-01-24' به ما داده شده و از ما خواسته اند که روزهای موجود (تاریخ) بین این دو تاریخ را تولید کنیم.
برای انجام این کار میتوان از چند روش مختلف استفاده کرد که در زیر جزئیات آنها آمده است:
1. استفاده از سابکوئری در MySQL:
یک روش موثر بدون نیاز به حلقه یا جدول موقتی، استفاده از سابکوئری است که تاریخها را تولید میکند. در مثال زیر، برای تولید تاریخها از CURRENT_DATE
استفاده میشود و مقادیر را از چندین زیرپرسش ترکیب کنیم:
SELECT a.Date
FROM (
SELECT CURDATE() - INTERVAL (a.a + (10 * b.a) + (100 * c.a) + (1000 * d.a)) DAY AS Date
FROM (SELECT 0 AS a 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 a
CROSS JOIN (SELECT 0 AS a 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 b
CROSS JOIN (SELECT 0 AS a 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 c
CROSS JOIN (SELECT 0 AS a 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 d
) a
WHERE a.Date BETWEEN '2010-01-20' AND '2010-01-24';
با اجرای این کد، میتوانید تاریخهای بین این دو تاریخ خاص را دریافت کنید.
2. استفاده از ویو (View) در MySQL:
روشی دیگر ایجاد ویوهایی برای تولید اعداد و تاریخهاست. در این روش، میتوانید یک ویو ایجاد کنید که تاریخها را از اعداد تولید شده استخراج کند.
CREATE VIEW digits AS
SELECT 0 AS digit 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;
CREATE VIEW numbers AS
SELECT ones.digit + tens.digit * 10 + hundreds.digit * 100 + thousands.digit * 1000 AS number
FROM digits AS ones,
digits AS tens,
digits AS hundreds,
digits AS thousands;
CREATE VIEW dates AS
SELECT SUBDATE(CURRENT_DATE(), number) AS date FROM numbers;
با این ویو به صورت زیر میتوانید تاریخهای مورد نظر را تولید کنید:
SELECT date FROM dates WHERE date BETWEEN '2010-01-20' AND '2010-01-24' ORDER BY date;
3. استفاده از تابع generate_series در PostgreSQL:
اگر از PostgreSQL استفاده میکنید، میتوانید از تابع generate_series
برای تولید تاریخها استفاده کنید:
SELECT day::date
FROM generate_series('2010-01-20', '2010-01-24', INTERVAL '1 day') day;
این دستور به شما این امکان را میدهد که به راحتی تاریخها را بین دو تاریخ مشخص تولید کنید.
4. استفاده از CTE در SQL Server
برای پیدا کردن روزهای بین دو تاریخ در SQL Server می توانیم از CTE و کوئری های بازگشتی استفاده کنید. ابتدا تعداد به تعداد فاصله روزهای بین دو تاریخ عدد تولید می کنید و سپس با استفاده از تابع DATEADD برای هر عدد تولید از روی تاریخ شروع (تاریخ کوچکتر) تاریخ های مورد نظر را تولید می کنید:
WITH Numbers AS (
SELECT 0 AS n
UNION ALL
SELECT n + 1
FROM Numbers
WHERE n < DATEDIFF(DAY, '2010-01-20', '2010-01-24')
)
SELECT DATEADD(DAY, n, '2010-01-20')
FROM Numbers