【问题标题】:MySQL - Ignore AND if no value existsMySQL - 如果不存在值,则忽略 AND
【发布时间】:2017-02-15 19:50:00
【问题描述】:

我有一个获取高级自定义字段数据的 Wordpress 的 MySQL 查询。如果 AND 行之一没有结果,则整个查询不提供任何结果。我想知道如果 AND 行没有结果,我是否可以在查询中添加一些忽略 AND 行的内容?

SELECT DISTINCT post_title,
wp0.post_id as the_post_id, 
wp1.meta_value as _sale_price,
wp2.meta_value as _regular_price,
wp3.meta_value as ex_diameter,
wp4.meta_value as ex_center,
wp5.meta_value as ex_length,
wp6.meta_value as ex_alloy,
wp7.meta_value as ex_butt_1,
wp8.meta_value as ex_butt_2,
wp9.meta_value as ex_taper_1,
wp10.meta_value as ex_taper_2,
wp11.meta_value as ex_center


from wp_postmeta as wp0
INNER JOIN wp_postmeta as wp1
ON wp1.post_id=wp0.post_id
INNER JOIN wp_postmeta as wp2
ON wp2.post_id=wp0.post_id
INNER JOIN wp_postmeta as wp3
ON wp3.post_id=wp0.post_id
INNER JOIN wp_postmeta as wp4
ON wp4.post_id=wp0.post_id
INNER JOIN wp_postmeta as wp5
ON wp5.post_id=wp0.post_id
INNER JOIN wp_postmeta as wp6
ON wp6.post_id=wp0.post_id
INNER JOIN wp_postmeta as wp7
ON wp7.post_id=wp0.post_id
INNER JOIN wp_postmeta as wp8
ON wp8.post_id=wp0.post_id
INNER JOIN wp_postmeta as wp9
ON wp9.post_id=wp0.post_id
INNER JOIN wp_postmeta as wp10
ON wp10.post_id=wp0.post_id
INNER JOIN wp_postmeta as wp11
ON wp11.post_id=wp0.post_id



INNER JOIN wp_posts as wpp
ON wp1.post_id=wpp.ID
WHERE wp1.post_id='39' 
AND wp1.meta_key='_sale_price'
AND wp2.meta_key='_regular_price'
AND wp3.meta_key='ex_diameter'
AND wp4.meta_key='ex_center'
AND wp5.meta_key='ex_length'
AND wp6.meta_key='ex_alloy'
AND wp7.meta_key='ex_butt_1'
AND wp8.meta_key='ex_butt_2'
AND wp9.meta_key='ex_taper_1'
AND wp10.meta_key='ex_taper_2'
AND wp11.meta_key='ex_center'

例如; wp3.meta_key='ex_diameter' 可能根本不存在,但不是得到一个带有空白 ex_diameter 的结果,而是整个结果是空的并且不返回任何行。

【问题讨论】:

  • 我回答中的 SQL 示例显示 LEFT JOIN not OUTER JOIN。另外,我想我希望 wpp 成为驾驶台。我会首先在FROM 子句中列出它......然后做一个WHERE wp.id = '39'。我会在FROM wpp 之后使用一系列外连接... LEFT JOIN wp_postmeta wp1 ON wp1.post_id = wpp.id AND wp1.meta_key='_sale_price'。我认为不需要wp0,您可以从wpp.id 获得post_id

标签: mysql wordpress advanced-custom-fields


【解决方案1】:

而不是...

 INNER JOIN wp_postmeta as wp11
 ON wp11.post_id=wp0.post_id

 WHERE ...
 AND wp11.meta_key='ex_center'

您可以使用“外连接”操作而不是“内连接”,将条件从 WHERE 子句移动到连接的 ON 子句,并删除任何需要非 NULL 值的条件wp11 中的任何列...

 LEFT JOIN wp_postmeta as wp11
 ON wp11.post_id=wp0.post_id
 AND wp11.meta_key='ex_center'

 WHERE ...

使用外连接,如果从 wp11 中没有找到匹配的行,则 wp11 中的所有列都将为 NULL。 (这就是为什么我们需要将条件从 WHERE 子句移到 ON 子句... WHERE 子句中的条件不能满足 NULL...

对任何可以接受“缺失”行的表重复相同的模式。


实际上,使用LEFT JOIN,您首先需要“驾驶”表。可能希望在 FROM 子句中首先使用 wp_posts wpp 表,并在外部连接条件中引用 wpp.id。我真的认为不需要wp0 引用,您可以从 wpp.id 获取 post_id

SELECT
  FROM wp_posts wpp
  LEFT JOIN wp_postmeta wp1 ON wp1.post_id=wpp.id AND wp1.meta_key='_sale_price'
  LEFT JOIN wp_postmeta wp2 ON wp2.post_id=wpp.id AND wp2.meta_key='...'
  LEFT JOIN wp_postmeta wp3 ON wp3.post_id=wpp.id AND wp3.meta_key='...'
  ...
  LEFT JOIN wp_postmeta wp11 ON wp11.post_id=wpp.id AND wp11.meta_key='ex_center'
 WHERE wpp.id = 39

我感觉您才刚刚开始体验使用 EAV 工作的快乐。让乐趣开始吧!


要回答您提出的问题...不,没有办法绕过AND condition,除非通过添加 OR 条件来修改条件...

AND ( condition OR some_other_condition )

MySQL 有时在 OR 条件下表现不佳(在性能方面)。

【讨论】:

  • spencer7593,请参阅我的问题中的**** UPDATE ****,谢谢。
  • “MySQL 有时在 OR 条件下表现不佳(在性能方面)” 非常正确,尤其是在 wp_postmeta 表有几十万行的 Wordpress 中。 ://