【问题标题】:How to make multiple AND conditions in the same query?如何在同一个查询中创建多个 AND 条件?
【发布时间】:2019-03-30 09:14:27
【问题描述】:

我正在尝试显示两个日期之间的条目。日期以'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?

【问题讨论】:

  • 您确定年份的差异(数据中的 2018 年和查询中的 2019 年)是有意的吗?
  • 你的查询会很慢:(

标签: mysql sql wordpress


【解决方案1】:

如果您只需要与您的条件相对应的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'

子查询恢复每条记录对应的开始和结束日期,外部查询对日期进行过滤。

【讨论】:

    【解决方案2】:

    你也可以使用这样的查询:

    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]> 
    

    【讨论】:

      猜你喜欢
      • 2022-12-11
      • 1970-01-01
      • 2014-06-13
      • 2017-09-09
      • 2023-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多