简体   繁体   English

需要产品清单和订单

[英]Need the list of products and orders

This is my homework task:这是我的家庭作业:

Products which were ordered along with the 5 most ordered products more than once and the count of orders they were included in. (Do not include the 5 most ordered products in the final result)与订购次数最多的 5 个产品一起订购超过一次的产品以及它们所包含的订单数。(最终结果中不包括订购最多的 5 个产品)

Products and orders are in same table.产品和订单在同一张表中。 Order detail contain Order detail ID, order id, product id, quantity.订单明细包含订单明细 ID、订单 ID、产品 ID、数量。

I've tried everything but I'm struggling with "along with" statement in the query.我已经尝试了一切,但我在查询中的“与”语句中苦苦挣扎。

Here is a query I have tried:这是我尝试过的查询:

select 
  productid,
  count
  (
    (select productid from orderdetails)
     and
    (select productid from orderdetails order by quantity desc limit 5)
  ) as ORDERS
from orderdetails 
group by productid
order by ORDERS desc

You select from orderdetails, aggregate to get one result row per product and you count.您从订单详细信息中进行选择,聚合以获得每个产品的一个结果行并进行计数。 It is very common to count rows with COUNT(*) , but you can also count expressions, eg COUNT(mycolumn) where you just count those that are not null.COUNT(*)计算行数是很常见的,但您也可以计算表达式,例如COUNT(mycolumn) ,您只计算那些非空的。 You are counting an expresssion (because it is not COUNT(*) but COUNT(something else) that you are using).您正在计算一个表达式(因为它不是COUNT(*)而是您正在使用的COUNT(something else) )。 The expression to test for null and count is测试 null 和 count 的表达式是

(select productid from orderdetails)
  and 
(select productid from orderdetails order by quantity desc limit 5)

This, however is not an expression that leads to one value that gets counted (when it's not null) or not (when it's null).然而,这不是一个表达式,它导致一个值被计数(当它不为空时)或不(当它为空时)。 You are selecting all product IDs from the orderdetails table and you are selecting all the five product IDs from the orderdetails table that got ordered with the highest quantity.您正在从 orderdetails 表中选择所有产品 ID,并从 orderdetails 表中选择订购数量最多的所有五个产品 ID。 And then you apply AND as if these were two booleans, but they are not, they are data sets.然后你应用AND就好像它们是两个布尔值一样,但它们不是,它们是数据集。 Apart from the inappropriate use of AND which is an operator on booleans and not on data sets, you are missing the point here that you should be looking for products in the same order, ie compare the order number somehow.除了不恰当地使用AND是布尔值而不是数据集的运算符之外,您在这里错过了应该以相同顺序查找产品的要点,即以某种方式比较订单号。

So all in all: This is completely wrong.总而言之:这是完全错误的。 Sorry to say that.很抱歉这么说。 However, the task is not at all easy in my opinion and in order to solve it, you should go slowly, step by step, to build your query.然而,在我看来,这项任务并不容易,为了解决它,你应该慢慢地、一步一步地构建你的查询。

Products which were ordered along with the 5 most ordered products more than once与 5 种订购最多的产品一起订购的产品不止一次

Dammit;该死的; such a short sentence, but that is deceiving ;-) There is a lot to do for us...这么短的一句话,但那是骗人的;-) 我们有很多事情要做......

First we must find the 5 products that got ordered most.首先,我们必须找到订购最多的 5 种产品。 That means sum up all sales and find the five top ones:这意味着总结所有销售额并找到前五名:

select productid
from orderdetails
group by productid
order by sum(quantity) desc
limit 5

(The problem with this: What if six products got ordered most, eg products A, B, and C with a quantity of 200 and products D, E, and F with a quantity of 100? We would get the top three plus two of the top 4 to 6. In standard SQL we would solve this with a ties clause, but MySQL's LIMIT doesn't feature this.) (问题是:如果订购最多的六种产品,例如产品 A、B 和 C 的数量为 200,而产品 D、E 和 F 的数量为 100,那么我们将得到前三名加上两个前 4 到 6。在标准 SQL 中,我们会用 ties 子句解决这个问题,但 MySQL 的LIMIT没有这个功能。)

Anyway.反正。 Now we are looking for products that got ordered with these five products along.现在我们正在寻找与这五种产品一起订购的产品。 Does this mean with all five at once?这是否意味着同时拥有所有五个? Probably not.可能不是。 We are rather looking for products that were in the same order with at least one of the top five.我们更愿意寻找与前五名中至少有一个处于同一订单的产品。

with top_5_products as
     (query above)
   , orders_with_top_5 as
     (select orderid
      from orderdetails 
      where productid in (select productid from top_5_products)
     )
   , other_products_in_order as
     (select productid, orderid
      from orderdetails 
      where orderid in (select orderid from orders_with_top_5)
      and productid not in (select productid from top_5_products)

And once we've got there, we must even find products that got ordered with some of the top 5 "more than once" which I interpret as to appear in at least two orders containing top 5 products.一旦我们到达那里,我们甚至必须找到“不止一次”订购前 5 种产品中的一些产品,我将其解释为至少出现在包含前 5 种产品的两个订单中。

with <all the above>
select productid
from other_products_in_order
group by productid
having count(*) > 1;

And while we have counted how many orders the products share with top 5 products, we are still not there, because we are supposed to show the number of orders the products were included in, which I suppose refers to all orders, not only those containing top 5 products.虽然我们已经计算了产品与前 5 种产品共享的订单数量,但我们仍然没有,因为我们应该显示产品包含的订单数量,我想这是指所有订单,而不仅仅是那些包含前 5 名产品。 That is another count, that we can get in the select clause for instance.这是另一个计数,例如我们可以在 select 子句中获得。 The query then becomes:然后查询变为:

with <all the above>
select
  productid,
  (select count(*) from orderdetails od where od.productid = opio.productid)
from other_products_in_order opio
group by productid
having count(*) > 1;

That's quite a lot for homework seeing that you are struggling with the syntax still.看到您仍在为语法而苦苦挣扎,这对于家庭作业来说是相当多的。 And we haven't even addressed that top-5-or-more ties problem yet (for which analytic functions come in handy).我们甚至还没有解决前 5 个或更多的关系问题(分析函数派上用场)。

The WITH clause is available since MySQL 8 and helps getting such a query that builds up step by step readable. WITH子句从 MySQL 8 开始可用,有助于获得这样一个逐步构建的查询可读性。 Old MySQL versions don't support this.旧的 MySQL 版本不支持这个。 If working with an old version I suggest you upgrade :-) Else you can use subqueries directly instead.如果使用旧版本,我建议您升级:-) 否则您可以直接使用子查询。

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

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