Выбор диапазона дат в 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)
Другие вопросы по тегам