mysql - HAVING vs WHERE vs GROUP BY 子句,何时使用它们以及是否使用''
问题描述
希望这篇文章能帮助我和许多像我一样的人更好地理解 WHERE、HAVING、GROUP BY 等问题。每个人都有自己的语法方式,因为在 MYSQL 中有不止一种方法可以使某些东西工作,这个想法是帮助我完成这项工作,同时也帮助整个社区:) 以下是设计我的查询的一种建议方法。
SELECT t1.post_id, t2.name,
MAX(case when meta_key = 'value' THEN `meta_value` ELSE NULL END) as Email,
MAX(CASE WHEN `meta_key` = 'value' THEN `meta_value` ELSE NULL END) as CustomerId,
MAX(CASE WHEN `meta_key` = 'value' THEN `meta_value` ELSE NULL END) as DeliveryDate,
MAX(CASE WHEN `meta_key` = 'value' THEN `meta_value` ELSE NULL END) as DeliveryTime,
MAX(CASE WHEN `meta_key` = 'value' THEN `meta_value` ELSE NULL END) as DeliveryType,
MAX(case when meta_key = 'value' THEN `meta_value` ELSE NULL END) as Zip,
MAX(case when meta_key = 'value' THEN `meta_value` ELSE NULL END) as OrderNote,
MAX(case when meta_key = 'value' THEN `meta_value` ELSE NULL END) as PaymentTotal,
MAX(case when meta_key = 'value' THEN `meta_value` ELSE NULL END) as OrderStatus
FROM table_A t1
inner join table_B t2 on find_in_set(t1.post_id, t2.payment_ids)
where OrderStatus rlike '%trans%|ready'
and DeliveryDate >= current_date - interval 7 day
and DeliveryType = 'pickup'
group by
t1.post_id,
t2.name
这会产生错误>>>>“#1054 - 'where 子句'中的未知列'DeliveryDate'”我认为它会产生此错误,因为“orderStatus”不是实际的列名,而是从另一列中提取的值,然后通过以下方式制作自己的专栏:
MAX(case when meta_key = '_order_status' THEN `meta_value` ELSE NULL END) as OrderStatus
所以我假设我需要在语句的 SELECT 区域和 WHERE 区域中将名称括在“”中。但是会产生错误 >>>>>>>>>>>>“警告:#1292 截断不正确的日期值:'DeliveryDate'”
为什么会这样,解决方案是什么?
编辑因为有些人建议不能以上述方式使用 WHERE 子句,所以我使用下面的代码使用了 HAVING 子句。这是代码:
选择.......^^从上面............
FROM table_A t1
inner join table_B t2 on find_in_set(t1.post_id, t2.payment_ids)
GROUP BY post_id
HAVING DeliveryDate = (DATE_SUB(CURDATE(), INTERVAL 7 DAY))
AND DeliveryType = 'pickup'
AND OrderStatus = 'ready'
OR OrderStatus = 'transit'
ORDER BY 'DeliveryTime' DESC
以上也不起作用。这里的问题是 AND 子句更重要,并且似乎淘汰了日期过滤器。当我使用此代码时,无论日期如何,它都会返回所有记录。
编辑 2 >>>>>>>>>> 也试过了,但它仍然没有过滤掉 3 个月大的条目
选择.......^^从上面............
FROM table_A t1
inner join table_B t2 on find_in_set(t1.post_id, t2.payment_ids)
GROUP BY post_id
HAVING MAX(CASE WHEN 'meta_key' = 'value' THEN 'meta_value' ELSE NULL END)>= current_date - interval 7 day
AND DeliveryType = 'pickup'
AND OrderStatus = 'ready'
OR OrderStatus = 'transit'
ORDER BY 'DeliveryTime' DESC
编辑 3 >>>>>>>>>> 简化代码。结果相同。即使使用 CURDATE() 仍然显示 3 个月前的记录
……………………………………………………………………………………………………………………
FROM table_A t1
inner join table_B t2 on find_in_set(t1.post_id, t2.payment_ids)
GROUP BY post_id
HAVING MAX(CASE WHEN 'meta_key' = 'value' THEN 'meta_value' ELSE NULL END)= CURDATE()
AND DeliveryType = 'pickup'
AND OrderStatus = 'ready'
OR OrderStatus = 'transit'
ORDER BY 'DeliveryTime' DESC
编辑 4 >>>>>>>>>>>>>>>>>>>>>> 最小的例子...
选择 t1.post_id,t2.name,
MAX(CASE WHEN `meta_key` = 'value' THEN `meta_value` ELSE NULL END) as DeliveryDate,
MAX(CASE WHEN `meta_key` = 'value' THEN `meta_value` ELSE NULL END) as DeliveryTime,
MAX(CASE WHEN `meta_key` = 'value' THEN `meta_value` ELSE NULL END) as DeliveryType,
MAX(case when meta_key = 'value' THEN `meta_value` ELSE NULL END) as OrderStatus
FROM table_A t1
inner join table_B t2 on find_in_set(t1.post_id, t2.payment_ids)
GROUP BY post_id
HAVING MAX(CASE WHEN 'meta_key' = 'value' THEN 'meta_value' ELSE NULL END)= CURDATE()
AND DeliveryType = 'pickup'
AND OrderStatus = 'ready'
OR OrderStatus = 'transit'
ORDER BY 'DeliveryTime' DESC
我希望这只会返回今天的记录。它返回所有时间的所有记录,同时满足其他 HAVING 子句要求
解决方案
您是正确的,WHERE 子句不能引用同一查询中的列别名。
这样想:
满足查询的第一步是从 FROM、JOIN 和 ON 子句构造一个虚拟表。
第二步是根据 WHERE 子句过滤该虚拟表。
第三步是根据需要减少虚拟表,根据 GROUP BY 和聚合函数(SUM、COUNT、GROUP_CONCAT 等)
然后,如有必要,HAVING 基于减少的数据进行过滤。(HAVING COUNT(*) > 1
例如。)
然后,SELECT 子句选择、计算并使用别名命名要从查询返回的列。
最后,ORDER BY 子句进行排序操作。
因此,当查询计划器执行 WHERE 过滤时,SELECT 子句中的别名和计算列值尚未在范围内。
解决方案是将一个查询嵌套在另一个查询中,如下所示:
SELECT q.* FROM (
SELECT a, b, c AS number
FROM tbl
WHERE whatever ) q
WHERE q.number > 2
别名或内部查询在外部查询的 WHERE 子句的范围内。
这种查询模式很常见,查询优化器会尽可能高效地处理它们。
而且,您违反了 wp_postmeta 将每个值表示为文本字符串的方式的限制。如果要对此类值进行日期运算,请先使用 STR_TO_DATE()。
推荐阅读
- html - 使用 Visual Basic 6 阅读网页
- image - Docker 镜像将被 kubernetes 谷歌云重读
- javascript - jQuery/JS:从数组和 DOM 中删除对象
- javascript - Javascript - 浏览器关闭后清除cookie?
- go - 如何从原始电子邮件中提取信息
- dll - InstallShield UseDLL() 在同一目录中找不到 dll 依赖项
- python - 通过字符串前缀加入熊猫数据帧
- javascript - 为什么我的函数不会返回用户输入的字符串
- kubernetes - k8s 在将 pod 分配给节点时考虑了什么?
- java - Spring Boot 2.x 不会在 JUnit 测试中加载 application.properties