【问题标题】:How can I sort data before grouping in MYSQL如何在MYSQL中分组之前对数据进行排序
【发布时间】:2009-12-29 10:56:28
【问题描述】:

我有一个大的 mysql 查询,它需要遍历 4 个表来获取我的应用程序的所有“项目”。每个项目可以有许多类别,每个用户最多可以有一个项目。项目和类别很简单:

SELECT Items.itemId, Items.name, Items.type, Categories.name AS category 
FROM Items 
LEFT JOIN ItemCategories ON Items.itemId = ItemCategories.itemId
LEFT JOIN Categories ON ItemCategories.categoryId = Categories.categoryId;

这会产生我想要的大部分数据。但是,我还需要知道每个项目是否由特定用户拥有。所以我简单地添加了另一个连接和一个布尔列:

SELECT Items.itemId, Items.name, Items.type, Categories.name AS category, 
UserItems.userId = 7654321 AS userHas FROM Items
LEFT JOIN ItemCategories ON Items.itemId = ItemCategories.itemId
LEFT JOIN Categories ON ItemCategories.categoryId = Categories.categoryId
LEFT JOIN UserItems ON Items.itemId = UserItems.itemId;

这样做的问题是它会产生很多不需要的结果。例如,如果我有 500 个用户,每个用户有 50 个项目,那么将有 25,000 行。由于数据库中只有大约 100 个项目,每个项目大约有 3 个类别,我只需要大约 300 行。基本上我不需要知道其他用户可能拥有的项目,只需要知道我感兴趣的特定用户。

我的下一步是尝试对行进行分组:

GROUP BY Items.itemId, Categories.name

但是,这并不能确保我的用户在 userHas 列中的数据得到保留。我试图 SORT BY userHas DESC,但这似乎是在 GROUP BY 之后应用的。

我感觉解决方案可能涉及以下功能之一:http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html 但我不知道什么或如何。我知道在一个查询中它甚至可能是不可能的。

这是一些输出(不使用 GROUP BY):

+--------+--------+-----------+----------+---------+
| itemId | name   | type      | category | userHas |
+--------+--------+-----------+----------+---------+
|      1 | Llama  | character | animal   |    NULL |
|      1 | Llama  | character | nice     |    NULL |
|      2 | Slug   | character | animal   |       0 |
|      2 | Slug   | character | animal   |       1 |
|      2 | Slug   | character | nasty    |       0 |
|      2 | Slug   | character | nasty    |       1 |
|      3 | Sloth  | character | animal   |       1 |
|      3 | Sloth  | character | animal   |       0 |
|      4 | Banana | character | fruit    |       0 |
|      4 | Banana | character | animal   |       0 |
+--------+--------+-----------+----------+---------+

我想要每个项目的id、名称、类型所有的类别以及用户是否有一个。与 GROUP BY Items.itemId 相同的数据集,Categories.name 看起来像:

+--------+--------+-----------+----------+---------+
| itemId | name   | type      | category | userHas |
+--------+--------+-----------+----------+---------+
|      1 | Llama  | character | animal   |    NULL |
|      1 | Llama  | character | nice     |    NULL |
|      2 | Slug   | character | animal   |       0 |
|      2 | Slug   | character | nasty    |       0 |
|      3 | Sloth  | character | animal   |       1 |
|      4 | Banana | character | animal   |       0 |
|      4 | Banana | character | fruit    |       0 |
+--------+--------+-----------+----------+---------+

Slug 的 userHas = 1 字段已在 GROUP BY 中丢失。我想保存它。

【问题讨论】:

  • 你想通过这个实现什么:UserItems.userId = 7654321?
  • 对不起,我应该说。这是我的示例用户的用户 ID 的布尔列。该列输出真或假取决于该行是否对应于该用户。
  • 在这种情况下,查看您想要实现的目标的样本可能会有所帮助。我自己也不是很清楚。
  • 为什么需要那个专栏?也许你想过滤结果?

标签: mysql join group-by sql-order-by


【解决方案1】:

更新:

这将选择所有项目并显示用户7654321 是否拥有它们。

SELECT  Items.itemId, Items.name, Items.type, Categories.name AS category,
        NOT(ISNULL(UserID)) AS userHas
FROM    Items
LEFT JOIN
        ItemCategories
ON      Items.itemId = ItemCategories.itemId
LEFT JOIN
        Categories
ON      ItemCategories.categoryId = Categories.categoryId
LEFT JOIN
        UserItems
ON      UserItems.itemId = Items.itemID
        AND UserItems.userId = 7654321

【讨论】:

  • 这是我首先尝试的。但它会过滤掉用户没有的项目,我想在标记用户拥有的项目的同时保留它们。
  • 天哪,太美了。非常感谢。
  • 不应该是NOT(ISNULL(UserID)吗?
  • 谢谢,你一定是mysql大师。
  • @peterjwest: 我在哪里注册? :)
【解决方案2】:

您是否尝试将UserHas 列添加到GROUP BY 子句?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-03
    • 1970-01-01
    • 2011-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-11
    相关资源
    最近更新 更多