2015-01-26 114 views
9

我正在尝试编写一个查询,查找每次在特定日期范围内发生在我的表中的同一个人。然后它将这个人分组并且将他们的花费总计在特定范围内。如果他们的消费习惯大于X金额,则在指定的日期范围内为此人返回每一行。不仅仅是分组总量。这是我到目前为止:MySQL - 组和总数,但返回每个组中的所有行

SELECT member_id, 
SUM(amount) AS total 
FROM `sold_items` 
GROUP BY member_id 
HAVING total > 50 

这是检索正确的总和返回成员花费超过50美元,但不是每一行。只是每个成员的总数和他们的总数。我目前正在查询整个表格,我没有添加日期范围。

+0

不可能。当你分组时,该组的所有成员行都折叠成一个代表性的行。如果你想要原始成员行,那么你不能使用'group by'。 – 2015-01-26 20:23:32

+0

同意。这是您希望在查询上具有应用程序层的位置,以提供报告所需的小计和细分。 – PaulProgrammer 2015-01-26 20:25:26

+1

您可以'与这个子查询加入原始表来返回所有相关的行。 – Barmar 2015-01-26 20:33:14

回答

14

JOIN这个子查询与原表:

SELECT si1.* 
FROM sold_items AS si1 
JOIN (SELECT member_id 
     FROM sold_items 
     GROUP BY member_id 
     HAVING SUM(amount) > 50) AS si2 
ON si1.member_id = si2.member_id 

一般的规则是由同一列(S)的子查询组,它的选择,然后你加入那与原始查询我们在同一列。

+0

这似乎解决了我的问题!谢谢!我从来不知道我可以使用JOIN编写嵌套的select语句。太棒了。 – 2015-01-26 20:49:19

+0

它不起作用,它不会为我返回所有摘要:http://pastebin.com/DhvrmNsq查询应该返回重复的结果(相同的设备和相同的时间),但它会丢失超过2个实例的重复项。 – singe3 2016-06-03 15:55:48

+1

您的子查询不正确。它只是从每个组中选择一个ID,而不是所有的ID。您需要选择要分组的同一列,然后在联接中使用这些列。 – Barmar 2016-06-03 16:00:49

0

有几种语法可以得到您要查看的结果,下面是使用内部联接来确保返回的所有行在由组返回的列表中具有member_id并且总计为每个某成员有:

SELECT si.*, gb.total from sold_items as si, (SELECT member_id as mid, 
SUM(amount) AS total 
FROM `sold_items` 
GROUP BY member_id 
HAVING total > 50) as gb where gb.mid=si.member_id; 
+0

请不要在答案中使用隐式连接。我们尝试提升ANSI连接。 – Barmar 2015-01-26 20:35:59

+0

我的道歉,有道理。 – 2015-01-28 09:32:05

1
SELECT member_id, amount 
FROM sold_items si 
INNER JOIN (SELECT member_id, 
SUM(amount) AS total 
FROM `sold_items` 
GROUP BY member_id 
HAVING total > 50) spenders USING (member_id) 

您已经构建的查询可以用作临时表来加入。如果member_id不是表格中的索引,则这将随着比例变慢。 单词spenders是一个表别名,您可以使用任何有效的别名代替它。

0

我认为,这可能帮助:

SELECT 
    member_id, 
    SUM(amount) AS amount_value, 
    'TOTAL' as amount_type 
FROM 
    `sold_items` 
GROUP BY 
    member_id 
HAVING 
    SUM(amount) > 50 

UNION ALL 

SELECT 
    member_id, 
    amount AS amount_value, 
    'DETAILED' as amount_type 
FROM 
    `sold_items` 
    INNER JOIN 
    (
     SELECT 
      A.member_id, 
      SUM(amount) AS total 
     FROM 
      `sold_items` A 
     GROUP BY 
      member_id 
     HAVING 
      total <= 50 
    ) AS A 
    ON `sold_items`.member_id = A.member_id 

上述查询的结果应该是这样的:

member_id  amount_value amount_type 
========================================== 
1    55    TOTAL 
2    10    DETAILED 
2    15    DETAILED 
2    10    DETAILED 

所以列amount_type将区分两个特定成员组