Как сделать несколько условий И в одном запросе? - PullRequest
0 голосов
/ 30 марта 2019

Я пытаюсь отобразить записи между двумя датами. Даты хранятся в этом формате 'dd/mm/YYYY'.

meta_id |    post_id |   meta_key         | meta_value  
5652    |    510     | _begin_date_course | 04/02/2018  
5756    |    512     | _begin_date_course | 04/02/2018  
5889    |    510     | _end_date_course   | 11/03/2019  
6002    |    512     | _end_date_course   | 04/02/2019  
..

Я пытаюсь вернуть post_id между двумя датами.

Если я попробую это:

SELECT * FROM wp_postmeta
WHERE (meta_key = '_begin_date_course' AND STR_TO_DATE(meta_value, '%d/%m/%Y') >= '2019-02-04')

или

SELECT * FROM wp_postmeta
WHERE (meta_key = '_end_date_course' AND STR_TO_DATE(meta_value, '%d/%m/%Y') <= '2020-06-06')

Это работает.

Но если я попробую с форматом AND, он не будет работать

SELECT * FROM wp_postmeta
WHERE (meta_key = '_begin_date_course' AND STR_TO_DATE(meta_value, '%d/%m/%Y') >= '2019-02-04')
AND (meta_key = '_end_date_course' AND STR_TO_DATE(meta_value, '%d/%m/%Y') <= '2020-06-06')

Возможно, потому что _begin_date_course и _end_date_course находятся в двух разных записях.

Как я могу получить post_id в диапазоне в этом состоянии?

Ответы [ 2 ]

0 голосов
/ 30 марта 2019

Вы также можете использовать запрос как этот:

SELECT
      p1.post_id
    , p1.meta_value as date_start
    , p2.meta_value as date_end
FROM wp_postmeta p1
LEFT JOIN wp_postmeta p2 ON p1.post_id = p2.post_id AND p2.meta_key = '_end_date_course'
WHERE 
    p1.meta_key = '_begin_date_course'
AND
     STR_TO_DATE(p1.meta_value, '%d/%m/%Y') >= '2018-02-04'
AND
     STR_TO_DATE(p2.meta_value, '%d/%m/%Y') <= '2020-06-06';

образец

MariaDB [test]> select * from wp_postmeta;
+----+---------+--------------------+------------+
| id | post_id | meta_key           | meta_value |
+----+---------+--------------------+------------+
|  1 |     510 | _begin_date_course | 04/02/2018 |
|  2 |     512 | _begin_date_course | 04/02/2018 |
|  3 |     510 | _end_date_course   | 11/03/2019 |
|  4 |     512 | _end_date_course   | 04/02/2019 |
+----+---------+--------------------+------------+
4 rows in set (0.001 sec)

MariaDB [test]> SELECT   p1.post_id
    -> , p1.meta_value as date_start
    -> , p2.meta_value as date_end
    -> FROM wp_postmeta p1
    -> LEFT JOIN wp_postmeta p2 ON p1.post_id = p2.post_id AND p2.meta_key = '_end_date_course'
    -> WHERE 
    -> p1.meta_key = '_begin_date_course'
    -> AND
    ->  STR_TO_DATE(p1.meta_value, '%d/%m/%Y') >= '2018-02-04'
    -> AND
    ->  STR_TO_DATE(p2.meta_value, '%d/%m/%Y') <= '2020-06-06';
+---------+------------+------------+
| post_id | date_start | date_end   |
+---------+------------+------------+
|     510 | 04/02/2018 | 11/03/2019 |
|     512 | 04/02/2018 | 04/02/2019 |
+---------+------------+------------+
2 rows in set (0.001 sec)

MariaDB [test]> 
0 голосов
/ 30 марта 2019

Если вам нужен только список post_id, который соответствует вашим критериям, вы можете использовать агрегацию с предложением HAVING для фильтрации, например:

SELECT post_id
FROM wp_postmeta
GROUP BY post_id
HAVING 
        MAX(CASE WHEN meta_key = '_begin_date_course' THEN STR_TO_DATE(meta_value, '%d/%m/%Y') END) >= '2019-02-04'
    AND MAX(CASE WHEN meta_key = '_end_date_course'   THEN STR_TO_DATE(meta_value, '%d/%m/%Y') END) <= '2020-06-06'

С другой стороны, если вы хотите вернуть все записи, вот решение с использованием оконных функций, доступное с MySQL 8.0.

SELECT * 
FROM (
    SELECT 
        p.*, 
        MAX(CASE WHEN meta_key = '_begin_date_course' THEN STR_TO_DATE(meta_value, '%d/%m/%Y') END) 
            OVER(PARTITION BY post_id) begin_date_course,
        MAX(CASE WHEN meta_key = '_end_date_course'   THEN STR_TO_DATE(meta_value, '%d/%m/%Y') END) 
            OVER(PARTITION BY post_id) end_date_course
    FROM wp_postmeta
) x
WHERE begin_date_course >= '2019-02-04' AND end_date_course <= '2020-06-06'

Подзапрос восстанавливает даты начала и окончания, соответствующие каждой записи, а внешний запрос выполняет фильтрацию по датам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...