简体   繁体   English

MYSQL子查询并计算包含值的行数

[英]MYSQL Subquery and count number of rows containing a value

I have two tables oc_order o and oc_order_total ot 我有两个表oc_order ooc_order_total ot

oc_order o has fields o.customer_id, o.date_added, o.email,o.total oc_order o具有字段o.customer_id, o.date_added, o.email,o.total

And oc_order_total ot has fields ot.code and ot.value oc_order_total ot具有字段ot.codeot.value

I want to show results only if customer orders more than 3 times that is if customer_id repeats thrice or more in the result and show ot.value where ot.code = 'shipping' 我只想在客户订单超过3次的情况下显示结果,即customer_id在结果中重复三次或更多,并显示ot.value where ot.code = 'shipping'

I am trying to do following 我正在尝试跟随


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


I am getting Invalid use of group error and I think I am not using subquery correctly in where clause. 我正在无效使用组错误,我想我在where子句中没有正确使用子查询。

You can not use SUM / COUNT in WHERE statement. 您不能在WHERE语句中使用SUM / COUNT You need to use for this HAVING operator. 您需要使用此HAVING运算符。 Try this query: 试试这个查询:

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

EDIT: Adding example with ot.value not affected by GROUP BY . 编辑:添加示例与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

Basically what happens here is that you pre-filter customers with previous query and then use these pre-filtered list to get individual orders for these customers meeting your criteria. 基本上,这里发生的事情是您用先前的查询预先过滤了客户,然后使用这些预先过滤的列表来为这些满足您条件的客户获取单个订单。 On this individual orders_id you can perform any operation without grouping cause you already eliminated customers not meeting your needs. 在这个单独的orders_id您可以执行任何操作而无需分组,因为您已经淘汰了不满足需求的客户。 Hope it helps. 希望能帮助到你。

NO, you are getting error cause your GROUP BY doesn't contains all the column listed in SELECT list and you can't use COUNT() aggregate function like that in WHERE condition; 不,由于遇到错误,因为GROUP BY不包含SELECT列表中列出的所有列,并且无法使用WHERE条件下的COUNT()聚合函数; it's only allowed in HAVING clause. 仅在HAVING子句中允许。 You can modify your query like 您可以像这样修改查询

SELECT o.date_added
     , o.email
     , o.total
     , ot.value
  FROM oc_order o
  JOIN oc_order_total ot 
    ON ot.order_id = o.order_id
  JOIN
     ( SELECT COUNT(customer_id) AS 'Orders Count'
            , customer_id
         FROM oc_order
        GROUP 
           BY customer_id 
     ) xxx 
    ON xxx .customer_id = o.customer_id
 WHERE  xxx.`Orders Count` > 3 
   AND ot.code = 'shipping';

For one thing, aggregates cannot be referenced in the WHERE clause. 一方面,无法在WHERE子句中引用聚合。

The predicates in the WHERE clause are evaluated when the rows are accessed. 访问行时将评估WHERE子句中的谓词。 At the time the rows are being retrieved, MySQL doesn't have any information about the value returned by aggregate functions (eg COUNT() ). 在检索行时,MySQL没有有关聚合函数返回的值的任何信息(例如COUNT() )。

The COUNT() aggregate will be evaluated after the rows are accessed, and after the GROUP BY operation. COUNT()的行被存取聚合将被评估,并且后GROUP BY操作。

An aggregate can be referenced in a HAVING clause, following the GROUP BY clause. 可以在GROUP BY子句之后的HAVING子句中引用聚合。

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

Note that the HAVING clause is evaluated after the GROUP BY operation, and after the values of the aggregate expressions are evaluated. 请注意,HAVING子句是 GROUP BY操作之后和聚合表达式的值之后进行求值的。 Much different than the WHERE clause. 与WHERE子句大不相同。


Also, the subquery is a bit odd. 而且,子查询有点奇怪。 Because it's being referenced in an equality comparison, the subquery can return at most one row. 因为在相等比较中被引用,所以子查询最多可以返回一行。 We don't see anything in the query that would prevent that, unless code is guaranteed to be unique in `ot_. 除非保证code在ot_中是唯一的,否则我们在查询中看不到任何阻止它的内容。

If code is unique, then we wouldn't need a subquery at all, we could just test for code. 如果code是唯一的,那么我们根本不需要子查询,只需测试代码即可。

 WHERE ot.code = 'shipping'

If there are multiple rows with "shipping" in the code column, we don't see any guarantee that the value column on those rows will be the same. 如果在code列中有多行带有“装运”,则我们无法保证这些行上的value列相同。 To test for any of the possible values, we could use an IN operator instead of the equality (scalar) comparison. 为了测试任何可能的值,我们可以使用IN运算符代替相等(标量)比较。 eg 例如

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

But that still looks really odd. 但这看起来仍然很奇怪。 What's strange is that it's using the same table as the outer query. 奇怪的是,它使用的表与外部查询相同 If we are using a subquery to lookup the set of value s related to a string code , that's usually a separate lookup table. 如果我们使用子查询来查找与字符串code相关的value集合,通常是一个单独的查找表。 And we'd normally prefer a JOIN operation rather than an IN (subquery) . 而且我们通常更喜欢JOIN操作而不是IN (subquery) Very strange. 很奇怪。


Also, the non-aggregate expressions in the SELECT list 另外,SELECT列表中的非聚合表达式

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

Do not appear in the GROUP BY clause. 不要出现在GROUP BY子句中。 Most relational databases will throw an error "non-aggregate in select not in group by" something of that ilk. 大多数关系数据库都会抛出类似错误,“在选择时不按组进行非聚合”。

But a MySQL extension will allow the query to run, but the values returned for the non-aggregates is indeterminate. 但是,MySQL扩展将允许查询运行,但是为非聚合返回的值是不确定的。 MySQL will return values for those expressions based on some row included in the collapsed set, but there's no guarantee which row that will be. MySQL将基于折叠集中包含的某些行返回这些表达式的值,但不能保证将是哪一行。

We can also get MySQL to throw an error like other databases, by including ONLY_FULL_GROUP_BY in the sql_mode variable. 通过在sql_mode变量中包含ONLY_FULL_GROUP_BY ,我们还可以使MySQL像其他数据库一样引发错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM