Выбор диапазона дат в SQL без поля DATE
У меня есть база данных MySQL, содержащая year
поле и week_number
поле. Это просто INT
поля. Я хотел бы иметь возможность выполнить запрос для выбора между инклюзивным диапазоном дат на основе номера недели и года, например:
SELECT * FROM table WHERE year BETWEEN 2000 AND 2002 AND week_number BETWEEN 50 AND 10
Но очевидно, что это не так, потому что в запросе нет понятия даты и времени. Я мог бы разделить этот конкретный пример на три отдельных запроса с небольшим анализом входных данных:
SELECT * FROM table WHERE year = 2000 AND week_number >= 50
SELECT * FROM table WHERE year = 2001
SELECT * FROM table WHERE year = 2002 AND week_number <= 10
Но я хотел бы знать, есть ли более эффективный и эффективный способ сделать это?
РЕДАКТИРОВАТЬ
Я думаю, что я, может быть, не ясно о реальной проблеме. То, что я хотел бы сделать, это запросить таким образом, чтобы я мог получить все даты между комбинацией начального года / недели и комбинацией конца года / недели. То есть в моем запросе выше я ожидаю, что будут возвращены следующие строки:
Year Week Number
2000 50
2000 51
2000 52
2001 1
2001 2
(...and so on for all weeks in 2001...)
2001 51
2001 52
2002 1
2002 2
(...and so on for weeks 3-8...)
2002 9
2002 10
5 ответов
DROP TABLE my_table;
CREATE TABLE my_table (val1 INT NOT NULL, val2 INT NOT NULL,PRIMARY KEY(val1,val2));
INSERT INTO my_table VALUES (2013,48),(2013,49),(2013,50),(2013,51),(2013,52),(2014,1),(2014,2),(2014,3),(2014,5);
SELECT * FROM my_table WHERE (val1,val2) >= (2013,50) AND (val1,val2) <= (2014,3);
+------+------+
| val1 | val2 |
+------+------+
| 2013 | 50 |
| 2013 | 51 |
| 2013 | 52 |
| 2014 | 1 |
| 2014 | 2 |
| 2014 | 3 |
+------+------+
SELECT * FROM table WHERE
CONCAT(year,week_number) BETWEEN CONCAT(YEAR(MY_DATE_START),WEEKOFYEAR(MY_DATE_START))
AND CONCAT(YEAR(MY_DATE_END),WEEKOFYEAR(MY_DATE_END))
Замените MY_DATE_START и MY_DATE_END на ваши даты.
Обновить
Подумав еще раз, вам может понадобиться левый блокнот с нулями все недели и приведение всех строк к целым числам, поэтому запрос становится следующим:
SELECT *
FROM table
WHERE CAST( CONCAT(year,LPAD(week_number,2,"0")) AS UNSIGNED )
BETWEEN CAST( CONCAT(YEAR(MY_DATE_START),LPAD(WEEKOFYEAR(MY_DATE_START),2,"0")) AS UNSIGNED )
AND CAST( CONCAT(YEAR(MY_DATE_END),LPAD(WEEKOFYEAR(MY_DATE_END),2,"0")) AS UNSIGNED )
Вы можете сделать это так:
SELECT
*
FROM table
WHERE DATE_ADD(MAKEDATE(year, 1), INTERVAL week_number WEEK) BETWEEN
DATE_ADD(MAKEDATE(2000, 1), INTERVAL 50 WEEK) AND
DATE_ADD(MAKEDATE(2002, 1), INTERVAL 10 WEEK)
Это то, что вы хотите?
SELECT * FROM table WHERE (year = 2000 AND week_number >= 50)
OR (year = 2001)
OR ( year = 2002 AND week_number <= 10)
Если вам нужно добавить результаты этих трех запросов, то есть выбрать все от 2000 слабых 50 до 2002 слабых 10 use OR
:
SELECT * FROM table WHERE (year = 2000 AND week_number >= 50) OR year = 2001 OR (year = 2002 AND week_number <= 10)