如何在同一查询中创建多个AND条件?

时间:2019-03-30 09:14:28

标签: mysql sql wordpress

我正在尝试显示两个日期之间的条目。日期以'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 :(得分:0)

如果仅需要符合条件的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'

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

答案 1 :(得分:0)

您还可以使用如下查询:

var list = await _dbContext.Entities
    .Select(x => new 
    { 
        OrderKey = _dbContext.Entities.Count(y =>
            x.Group == y.Group
                && y.Value < x.Value),
        Value = x,
     })
     .Where(x => x.OrderKey < 3)
     .OrderBy(x => x.OrderKey)
     .Select(x => x.Value)
     .ToListAsync(cancellationToken);

样本

IQueryable<T>