MYSQL子查询和计数包含值的行数

时间:2016-09-02 21:41:33

标签: mysql

我有两张表oc_order ooc_order_total ot

oc_order o包含字段o.customer_id, o.date_added, o.email,o.total

oc_order_total ot包含字段ot.codeot.value

我希望仅在客户订单超过3次时显示结果,如果customer_id在结果中重复三次或更多次并显示ot.value where ot.code = 'shipping'

我正在尝试关注


SELECT COUNT(o.customer_id) AS 'Orders Count', o.date_added, o.email,o.total, ot.value
FROM oc_order o
Inner join oc_order_total ot ON ot.order_id = o.order_id
WHERE count(o.customer_id) > 3 AND ot.value = (select value from oc_order_total where code = 'shipping' )
GROUP BY o.customer_id


我无法使用组错误,我认为我没有在where子句中正确使用子查询。

3 个答案:

答案 0 :(得分:1)

您无法在SUM声明中使用COUNT / WHERE。您需要使用此HAVING运算符。试试这个问题:

SELECT COUNT(o.customer_id) AS 'Orders Count', o.date_added, o.email,o.total, ot.value

FROM oc_order o
INNER JOIN oc_order_total ot ON ot.order_id = o.order_id AND 

WHERE ot.code IN (select value from oc_order_total where code = 'shipping' )

GROUP BY o.customer_id
HAVING count(o.customer_id) > 3

编辑:添加ot.value不受GROUP BY影响的示例。

SELECT o.order_id, q.orders_count AS 'Orders Count', o.date_added, o.email,o.total, ot.value

FROM oc_order o
INNER JOIN oc_order_total ot ON ot.order_id = o.order_id
INNER JOIN (SELECT o.customer_id, COUNT(o.customer_id) AS orders_count

FROM oc_order o
INNER JOIN oc_order_total ot ON ot.order_id = o.order_id

WHERE ot.code IN (select value from oc_order_total where code = 'shipping' )

GROUP BY o.customer_id
HAVING count(o.customer_id) > 3) AS q ON q.customer_id = o.customer_id

基本上,这里发生的是您使用先前的查询预先过滤客户,然后使用这些预先过滤的列表来获得符合您条件的这些客户的单独订单。在这个人orders_id上,您可以执行任何操作而无需分组,因为您已经淘汰了不满足您需求的客户。希望它有所帮助。

答案 1 :(得分:1)

不,您收到错误导致GROUP BY未包含SELECT列表中列出的所有列,并且您无法在{{1}中使用COUNT()聚合函数条件它只允许在WHERE条款中。您可以像

一样修改查询
HAVING

答案 2 :(得分:0)

首先,WHERE子句中不能引用聚合。

访问行时,将评估WHERE子句中的谓词。在检索行时,MySQL没有关于聚合函数返回的值的任何信息(例如COUNT())。

在访问行之后,以及COUNT()操作之后,将对GROUP BY聚合进行评估。

聚合可以在HAVING子句中引用GROUP BY子句。

 GROUP BY ...
HAVING COUNT(...) > 3

请注意,在 GROUP BY操作之后评估HAVING子句,并在评估聚合表达式的值之后 。与WHERE子句有很大不同。

此外,子查询有点奇怪。因为它是在相等比较中引用的,所以子查询最多只能返回一行。我们在查询中看不到任何会阻止这种情况的内容,除非{1_}中保证code是唯一的。

如果code是唯一的,那么我们根本不需要子查询,我们可以只测试代码。

 WHERE ot.code = 'shipping'

如果code列中有多个“发货”行,我们不会保证这些行上的value列会相同。要测试任何可能的值,我们可以使用IN运算符而不是相等(标量)比较。例如

 WHERE ot.value IN ( SELECT v.value 
                       FROM oc_order_total v
                      WHERE v.code = 'shipping'
                   )

但这仍然看起来很奇怪。奇怪的是,它使用相同的表作为外部查询。如果我们使用子查询来查找与字符串value相关的code集合,那么这通常是一个单独的查找表。我们通常更喜欢JOIN操作,而不是IN (subquery)。很奇怪。

此外,SELECT列表中的非聚合表达式

 o.date_added, o.email, o.total, ot.value

不要出现在GROUP BY子句中。大多数关系数据库会抛出一个错误“非聚合在选择中而不是在组中”等等。

但MySQL扩展将允许查询运行,但非聚合返回的值是不确定的。 MySQL将根据折叠集中包含的某些行返回这些表达式的值,但不保证将会是哪一行。

我们还可以通过在ONLY_FULL_GROUP_BY变量中包含sql_mode来让MySQL像其他数据库一样抛出错误。