【问题标题】:SQL GROUP BY (Multiple groups)SQL GROUP BY(多个组)
【发布时间】:2014-09-28 17:35:15
【问题描述】:

edit:似乎在 sqlfiddle 中工作......一定是在其他地方发生错误。谢谢大家。


http://sqlfiddle.com/#!2/f867c/1


我真的被 SQL 中的计数和分组所困扰。

重要的表是transaction_items——如果有人以每辆 100 磅购买 4 辆相同的自行车,那么在transaction_items 中插入四行,每个数量一行(这样做是有原因的,我不想要quantity 列。

我需要做的是从transaction_items 获取所有记录,其中charge_id = '12345' 并按transaction_items.usersid 和transaction_items.item_code 对它们进行分组 - 最终给我一个组列表,每个组与一个唯一用户和独特的产品。因此,如果购物车中有多个产品,则用户可以拥有多个组。如果用户 1 购买了 2 x 商品 1 和 4 x 商品 2,则用户 1 将分为两组,一组用于商品 1,计数为 2,一组用于商品 2,计数为 4。目前,我似乎只能得到一组。

所以如果我在 transaction_items 中有这个:

|  id  |  charge_id  |  usersid  |  item_code  |
|   1  |      12345  |       12  |         66  |
|   2  |      12345  |       12  |         66  |
|   3  |      66666  |       11  |         66  |
|   4  |      12345  |       12  |         66  |
|   5  |      12345  |        6  |         22  |
|   6  |      77777  |       10  |         66  |
|   7  |      12345  |       12  |         66  |
|   8  |      44444  |       23  |         66  |
|   9  |      12345  |        6  |         22  |

我想先将数据按charge_id AND usersid AND item_code 分组,我想取回这些数据:

Array
(

    // The array should contain arrays for each pair of usersid's and item_codes, that all have the same charge_id

    [0] => Array
        (
            //This is a unique group for usersid and item_code

            [charge_id] => '12345'
            [usersid] => '12' 
            [item_code] => '66'
            [num_of_records] => '4'          
        )
    [1] => Array
        (
            //This is a unique group for usersid and item_code

            [charge_id] => '12345'
            [usersid] => '6'
            [item_code] => '22'
            [num_of_records] => '2'          
        )
)

所以我希望得到一个数组:

  1. 将所有具有相同charge_id、userid 和item_code 的记录分组
  2. 以可用的格式获取数据,并带有计数(就像数量一样)
  3. 计数(数量)应仅针对每个组,而不是所有记录

我现在得到的似乎只是一个产品 ID、一个用户 ID,而是反映所有用户和项目的记录总数,这与我的目标完全相反! (下面的虚拟输出反映了上面示例表的使用):

Array
(
    [0] => Array
        (
            [charge_id] => '12345'
            [usersid] => '12'
            [item_code] => '66'
            [num_of_records] => '6'          
        )
)

我现在的查询:

$items = $db->query("
                SELECT 
                    count(transaction_items.id) as num_of_records,
                    transaction_items.*
                FROM 
                    transaction_items 
                WHERE
                    transaction_items.charge_id = :charge
                AND
                    transaction_items.lmsid = :lmsid
                GROUP
                BY
                    transaction_items.usersid,
                    transaction_items.charge_id,
                    transaction_items");

我错过了什么?

谢谢!


编辑和更新

这完全取决于 WHERE 子句。当我删除它时,查询可以正常工作,但会从 items 表中收集所有记录,而我只想要 charge_id = '12345' 的那些。因此,我认为这个问题的主题与 GROUP BY 和 WHERE 的组合使用以及为什么我没有得到我期望的结果密切相关。

为了简化问题,现在查询是:

$items = $db->query("SELECT 
                        count(transaction_items.id) as num_of_records,
                        item_code, 
                        usersid
                    FROM 
                        transaction_items
                    WHERE
                        charge_id = '12345'
                    GROUP
                    BY
                        usersid,
                        charge_id,
                        item_code
                        ");

【问题讨论】:

  • transaction_items.* 是个坏主意。列出你的字段名称。
  • 你说得对,WHERE 子句将其限制为带回一条记录,但如果没有 WHERE charge_id = :charge,我将从 transaction_items 表中获取每条记录 - 我如何将其过滤到特定的charge_id 值?我现在已经单独列出了transaction_items.*,我不知道为什么我一开始没有。

标签: mysql sql group-by grouping


【解决方案1】:

不确定我是否遵循 - 你是这个意思吗?

CREATE TABLE  transaction_items
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,charge_id  INT NOT NULL
,usersid  INT NOT NULL
,item_code INT NOT NULL
);

INSERT INTO transaction_items VALUES
(1  ,12345  ,12  ,66),
(2  ,12345  ,12  ,66),
(3  ,66666  ,11  ,66),
(4  ,12345  ,12  ,66),
(5 ,12345 , 6 ,22),
(6 ,77777 ,10 ,66),
(7 ,12345 ,12 ,66),
(8 ,44444 ,23 ,66),
(9 ,12345 , 6 ,22);

SELECT charge_id
     , usersid
     , item_code
     , COUNT(*) 
  FROM transaction_items 
 GROUP 
    BY charge_id
     , usersid
     , item_code;
+-----------+---------+-----------+----------+
| charge_id | usersid | item_code | COUNT(*) |
+-----------+---------+-----------+----------+
|     12345 |       6 |        22 |        2 |
|     12345 |      12 |        66 |        4 |
|     44444 |      23 |        66 |        1 |
|     66666 |      11 |        66 |        1 |
|     77777 |      10 |        66 |        1 |
+-----------+---------+-----------+----------+

编辑:我仍然很困惑......

SELECT charge_id
     , usersid
     , item_code
     , COUNT(*)
  FROM transaction_items
 WHERE charge_id = 12345
 GROUP
    BY charge_id
     , usersid
     , item_code;
+-----------+---------+-----------+----------+
| charge_id | usersid | item_code | COUNT(*) |
+-----------+---------+-----------+----------+
|     12345 |       6 |        22 |        2 |
|     12345 |      12 |        66 |        4 |
+-----------+---------+-----------+----------+

!?!?!

【讨论】:

  • 你在正确的轨道上,但你在那里发布的内容是我已经拥有的。查看上面的表格,您将在查询中添加什么以获取 charge_id = '12345' 所在的行,因为 WHERE 子句仅获取一行,并且从其组合的所有行中获得总数。如果没有 WHERE 子句,我会得到所有行。
  • 根据您的编辑,我的输出将是 charge_id = 12345、usersid = 6、COUNT(*) = 6。它似乎只检索第一行数据和所有行的计数。
  • charge_id = 12345 来自 where 子句。 usersid = 6我不知道它为什么要针对一个记录,也许是第一个?和 'COUNT(*)= 6' 是因为单条记录返回所有记录的总数,其中包含 WHERE 子句charge_id -> 甚至那些它没有返回的记录(上表中的 IE 2 + 4 返回到 6 ,只有一条记录)。
  • 但这似乎是你想要的!?!?!
  • 一点也不,我完全按照您在编辑中发布的内容,两个单独的行,每个唯一用户ID/项目代码对匹配的记录返回。目前,我只是用所有行的单个 COUNT 值返回一行。让我构建一个 SQLFIDDLE。
【解决方案2】:

您更新后的查询对我来说看起来不错,尽管我不确定 amount_paid 和 valid_days 列不属于 GROUP BY 或在您的任何示例中列出.. 这些其他聚合函数?

你确定你的数据和你期望的一样吗?运行一个

SELECT * FROM transaction_items WHERE charge_id = :charge_id 

以确保您有多个单独的组。你确定你没有遗漏一些数据吗?

另外你是GROUPing BY courseid 而不是item_code,对吗?

更新后:

这更有意义,但您的示例查询现在应该可以工作了。

我希望你有一些JOINs,可能是一个LEFT JOIN,它返回你期望一个id 的null,因此所有nulls 都被组合在一起。

尝试一点一点地分解您的查询,并确保所有单独的部分都按预期工作。

【讨论】:

  • 是的,我应该强调我的示例已经大大简化以“消除”问题,尽管我认为它现在可能导致相反的结果。让我进行一些编辑以清除云层。
  • 感谢您的更新和帮助。不幸的是,我已经删除了查询,您可以看到我目前正在测试的内容。我现在正在构建一个 SQLFIDDLE
  • @Arbiter,那个查询没问题,你的数据一定是朗姆酒。
  • 是的,SQL FIDDLE 确认 -- sqlfiddle.com/#!2/f867c/1 -- 这让我发疯。我现在必须睡觉,所以我会在 6 小时后起床时回来。为调查这个男孩和女孩干杯!
  • 现在,如果一开始就提供(或请求)一个小提琴就好了;-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-21
  • 2022-01-15
  • 2018-01-30
  • 2020-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多