【问题标题】:MySql query not returning correct dataMySql 查询没有返回正确的数据
【发布时间】:2016-03-11 21:50:14
【问题描述】:

我有一个 Wordpress MySQL 数据库,我需要创建一个自定义查询以使用 SQL。我正在尝试返回“date_start”值小于当天且“date_end”值大于或等于当天的当前事件(帖子)。我知道应该返回一条数据记录,但当我尝试同时搜索“date_start”和“date_end”时没有返回任何内容

这是我的旧 SQL 语句:

select ID, post_name, meta_id, meta_key, meta_value from wp_posts inner join wp_postmeta on wp_posts.ID = wp_postmeta.post_id and ((meta_key='date_end' and meta_value >= CURDATE() + interval 1 day) and (meta_key='date_start' and meta_value < CURDATE())) where post_type='programs' order by meta_value

新的 SQL 语句:

    SELECT
    ID,
    post_name,
    (SELECT meta_value FROM wp_postmeta WHERE wp_postmeta.post_id = ID AND meta_key = 'date_start') AS 'date_start',
    (SELECT meta_value FROM wp_postmeta WHERE wp_postmeta.post_id = ID AND meta_key = 'date_end') AS 'date_end'
FROM wp_posts
WHERE
    post_type = 'programs'
    AND ((CURDATE() >= (SELECT meta_value FROM wp_postmeta WHERE wp_postmeta.post_id = ID AND meta_key = 'date_start'))
    AND (CURDATE() <= (SELECT meta_value FROM wp_postmeta WHERE wp_postmeta.post_id = ID AND meta_key = 'date_end')))
ORDER BY `wp_posts`.`ID` ASC

返回的日期是:

ID      post_name                   date_start  date_end
1221    culture-analytics           20160307    20160610
2446    culture-analytics-tutorials 20160308    20160311

我还尝试过内部连接的 date_start 和 date_end 部分在 WHERE 子句中的位置。

重要提示:wp_postmeta 是多对​​一模式,而 'date_start' 和 'date_end' 是单独的记录,但都指向同一个 PostID

似乎是什么问题。

【问题讨论】:

  • meta_value &gt;= CURDATE() + interval 1 day 不等于“大于等于今天”,是“大于等于明天”。此外,如果值是字符串,您可能需要进行一些类型转换以获得预期/需要的比较结果。
  • @Uueerdo 是的,我知道大于或等于我了解那部分。如果我取出“date_start”部分或“date_end”部分,则返回记录。但如果我同时包含两者,则不会返回任何内容。所以它确实识别并相应地转换日期比较
  • 第二个meta_key条件前改为OR

标签: mysql wordpress inner-join where-clause date-comparison


【解决方案1】:

您对 meta_key 有两个相互冲突的约束。您的查询要求 meta_key 同时等于“date_start”和“date_end”。

不妨试试这样的:

SELECT
    ID,
    post_name,
    meta_id,
    (SELECT meta_value FROM wp_postmeta WHERE wp_postmeta.post_id = ID AND meta_key = 'date_start') AS 'date_start',
    (SELECT meta_value FROM wp_postmeta WHERE wp_postmeta.post_id = ID AND meta_key = 'date_end') AS 'date_end'
FROM wp_posts
WHERE
    post_type = 'programs'
    AND (SELECT meta_value FROM wp_postmeta WHERE wp_postmeta.post_id = ID AND meta_key = 'date_start') < CURDATE()
    AND (SELECT meta_value FROM wp_postmeta WHERE wp_postmeta.post_id = ID AND meta_key = 'date_end') >= (CURDATE() + INTERVAL 1 DAY)
ORDER BY 4

我无权访问 Wordpress 数据库,所以我没有运行它,但它可能会工作...

【讨论】:

  • 谢谢你的帮助,我所做的唯一改变是将 CURDATE() 放在“WHERE”子句中的“select”语句之前,但是它返回的记录比它应该。该额外记录的 date_end 是 20160610
  • 您可以发布您正在使用返回的数据集的实际查询吗?
  • 发布了你的版本并返回了数据集
  • Well CURDATE()
  • 明白了,抱歉。我现在必须找到一种方法来排除那个。
【解决方案2】:

@obe 在他的回答中发现了您原始查询的核心问题;但我会通过额外的连接而不是四个子查询来解决它:

SELECT ID, post_name, meta_id
   , beginMeta.meta_key As beginKey, endMeta.meta_key AS endKey
   , beginMeta.meta_value AS beginDate
   , endMeta.meta_value AS endDate
FROM wp_posts 
INNER JOIN wp_postmeta AS endMeta 
   ON wp_posts.ID = endMeta.post_id 
   AND endMeta.meta_key='date_end' 
   AND endMeta.meta_value >= CURDATE() + interval 1 day 
INNER JOIN wp_postmeta AS beginMeta 
   ON wp_posts.ID = beginMeta .post_id 
   AND beginMeta.meta_key='date_start' 
   AND beginMeta.meta_value < CURDATE() 
WHERE post_type='programs' 
ORDER BY beginDate, endDate
;

编辑:假设 (post_id, meta_key) 组合在 wp_postmeta 中是唯一的。

【讨论】:

  • 这确实会表现得更好......只需注意在第二个查询中它应该是“beginMeta.meta_key”和“beginMeta.meta_value”,并且在ORDER BY中你必须明确写“ beginMeta.meta_value”和“endMeta.meta_value”...
  • ORDER BY 可以使用别名......哦,doh......是的,第二个是复制粘贴的错误。正在修复....
  • 哈哈,我不明白为什么会出现一条额外的记录。,以 20160610 结束的记录
  • @mattgcon 正如 obe 在他的评论链中所说,该日期范围满足您的标准。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-23
  • 2014-06-16
  • 2020-05-31
  • 1970-01-01
  • 1970-01-01
  • 2018-08-04
相关资源
最近更新 更多