1

去年我一直在大量使用 stackoverflow - 一个优秀的来源,拥有伟大的贡献者。现在是我请求帮助的时候了。

设置正常:Orders、OrderArticles 和 Articles

我想获得去年销售的文章总量,但仅限于最好的 5 周

没关系 WEEK 函数和 UNIXTIME 等等等等 - 我已经涵盖了。我的问题是是否可以不使用存储过程或函数。

我为每周和文章的摘要创建了一个子查询,并按总和降序排列结果。现在 - 我只需要将查询限制为 5。很简单,但我还必须过滤 ArticleID 上的结果,但是因为我在子查询中,所以我无权访问外部 ArticleID,它也无济于事加入结果 - 为时已晚 ;-)

语法(很难理解没有实际的 sql,对吧......?)

SELECT a.ID, [more fields], omg.total
FROM Articles AS a
LEFT JOIN
(
    SELECT weeklytotals.articleID, weeklytotals.total
    FROM
    (
        SELECT SUM(ra.quantity) AS total, ra.articleID AS articleID
        FROM OrderArticles ra
        INNER JOIN Orders r
            ON ra.orderID = r.ID
        WHERE r.timeCreated >= UNIX_TIMESTAMP('2011-06-30')
        GROUP BY ra.articleID, WEEK(FROM_UNIXTIME(r.timeCreated))
        ORDER BY SUM(ra.quantity) DESC
    ) AS weeklytotals
    WHERE omg.articleID = a.ID --<-- THIS IS NOT WORKING BUT NECESSARY!
    LIMIT 0, 5
) AS omg
ON omg.articleID = a.ID
WHERE a.isEnabled = 1 --more WHERE-thingys 

这将返回前 5 篇文章并将它们与正确的文章联系起来。耶。

我省略了 SUM 函数(它可以进入 omg-SELECT)。

你明白吗?我明白我想要什么吗?是的,我们当然愿意!

提前谢谢。

编辑:条件已经改变 - 这让我的生活更轻松,但我仍然想知道是否有解决问题的方法。

4

1 回答 1

1

如果您要求omg子查询使用a表中的数据,请将其放入SELECT部分而不是FROM部分。使用 mysql 文档中的术语,您希望相关子查询的结果在外部结果集中显示为标量操作数。

您写到对总和感兴趣,即每篇文章只有一个数字,尽管您SUM从示例查询中省略了。我的方法依赖于这个总和,如果你真的需要最好的五周中的每一周都有不同的值,那么可能会以一种糟糕的方式打破。

SELECT a.ID, [more fields], IFNULL(SUM(
    (
        SELECT SUM(ra.quantity) AS total
        FROM OrderArticles ra
        INNER JOIN Orders r
           ON ra.orderID = r.ID
        WHERE ra.articleID = a.ID -- <-- reference a.ID here
          AND r.timeCreated >= UNIX_TIMESTAMP('2011-06-30')
        GROUP BY WEEK(FROM_UNIXTIME(r.timeCreated))
        ORDER BY SUM(ra.quantity) DESC
        LIMIT 0, 5
    )), 0) AS total
FROM Articles AS a
WHERE a.isEnabled = 1 --more WHERE-thingys 
GROUP BY a.ID

我不是在这里说任何关于性能的事情。以这种方式放置子查询,它将针对结果集中的每一行执行。因此,如果您有大量文章,实际使用可能会太慢。但如果发生这种情况,我怀疑存储过程或类似的技巧会更好。

编辑:我发现我原来的建议,它使用嵌套两层深的子查询,不允许访问最里面的子查询来使用最外面的列。但是在 sqlfiddle 上玩弄这个我还发现可以安全地将子查询的结果传递给 sum,从而避免一级嵌套。因此,上面的代码实际上已经由 MySQL 服务器检查并执行,因此应该可以按预期工作。

于 2012-06-26T12:59:57.493 回答