Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 按范围内用户数划分的SQL组_Mysql_Sql - Fatal编程技术网

Mysql 按范围内用户数划分的SQL组

Mysql 按范围内用户数划分的SQL组,mysql,sql,Mysql,Sql,我有以下查询,它将返回表事务中赚取100美元到200美元的用户数 SELECT COUNT(users.id) FROM transactions LEFT JOIN users ON users.id = transactions.user_id WHERE transactions.amount > 100 AND transactions.amount < 200 我希望对其进行扩展,以便查询能够以以下格式返回数据: COUNT(users.id) : amou

我有以下查询,它将返回表事务中赚取100美元到200美元的用户数

SELECT COUNT(users.id)
FROM transactions
LEFT JOIN users ON users.id = transactions.user_id
WHERE transactions.amount > 100 AND transactions.amount < 200
我希望对其进行扩展,以便查询能够以以下格式返回数据:

COUNT(users.id)    :     amount
1678               :     0-100
559                :     100-200
13                 :     200-300

如何执行此操作?

您可以在聚合函数中使用CASE表达式,该表达式将在列中获得结果:

SELECT 
  COUNT(case when amount >= 0 and amount <= 100 then users.id end) Amt0_100,
  COUNT(case when amount >= 101 and amount <= 200 then users.id end) Amt101_200,
  COUNT(case when amount >= 201 and amount <= 300 then users.id end) Amt201_300
FROM transactions
LEFT JOIN users 
  ON users.id = transactions.user_id;
然后,您可以使用此表连接到当前表,并按范围值分组:

select count(u.id) Total, concat(start_range, '-', end_range) amount
from transactions t
left join users u
  on u.id = t.user_id
left join report_range r
  on t.amount >= r.start_range
  and t.amount<= r.end_range
group by concat(start_range, '-', end_range);
选择计数(u.id)总计、浓度(起始范围、-、结束范围)金额
来自交易t
左加入用户u
on u.id=t.user\u id
左连接报告\u范围r
在t.amount>=r.start\U范围内

而t.amount一种方法是在你的小组中使用case/when语句

SELECT
-- NB this must match your group by statement exactly 
-- otherwise you will get an error
CASE 
    WHEN amount <= 100
    THEN '0-100'
    WHEN amount <= 200
    THEN '100-200'
    ELSE '201+'
END Amount,
COUNT(*)
FROM  
    transactions
GROUP BY
CASE 
    WHEN amount <= 100
    THEN '0-100'
    WHEN amount <= 200
    THEN '100-200'
    ELSE '201+'
END
如果您希望完全通用:

SELECT
    concat(((amount DIV 100) * 100),'-',(((amount DIV 100) + 1) * 100)) AmountGroup,
    COUNT(*)
FROM  
    transactions
GROUP BY
    AmountGroup

比尔博,我试着发挥创造力,找到了一个非常好的解决方案[对于那些热爱数学的人(像我一样)]
当MySQL整数除法运算符解决我们的问题时,总是令人惊讶

DROP SCHEMA IF EXISTS `stackoverflow3`;
CREATE SCHEMA `stackoverflow3`;
USE `stackoverflow3`;

CREATE TABLE users (
  id INT UNSIGNED PRIMARY KEY NOT NULL AUTO_INCREMENT,
  name VARCHAR(25) NOT NULL DEFAULT "-");

CREATE TABLE transactions(
  id INT UNSIGNED PRIMARY KEY NOT NULL AUTO_INCREMENT,
  user_id INT UNSIGNED NOT NULL,
  amount INT UNSIGNED DEFAULT 0,
  FOREIGN KEY (user_id) REFERENCES users (id));

INSERT users () VALUES (),(),();
INSERT transactions (user_id,amount)
  VALUES (1,120),(2,270),(3, 350),
    (2,500), (1,599), (1,550), (3,10),
    (3,20), (3,30), (3,50), (3,750);

SELECT
  COUNT(t.id),
  CONCAT(
    ((t.amount DIV 100)*100)," to ",((t.amount DIV 100 + 1)*100-1)
  ) AS amount_range
FROM transactions AS t
GROUP BY amount_range;

等待您的提问,巴金斯先生。

为什么不只是三个查询?这只是一个简化的示例,实际上我需要更多的范围。像这样的存储桶可以帮助EXCEL编写sql。这真是太好了,就速度而言,它与使用多个查询相比如何?另外,您不需要使用关键字“as”吗?不需要@DanyCaissy
作为
注意,这比另一个答案更通用,因为你可以定义你的函数来进行任何类型的分组,你将得到行而不是列。实际上,我正在用一个通用的答案更新我的答案,该答案使用范围表或派生表。一件事是,你正在使用SQL Server语法来处理MySQL标记的问题,你可能想现在在路上更新它,所以我明天会更新它。不错,是的,我们说的是同一件事,除了用不同的语言。我一定很喜欢整数数学为你带来改变;)
select count(u.id) Total, concat(start_range, '-', end_range) amount
from transactions t
left join users u
  on u.id = t.user_id
left join
(
  select 0 start_range, 100 end_range union all
  select 101 start_range, 200 end_range union all
  select 201 start_range, 300 end_range 
) r
  on t.amount >= r.start_range
  and t.amount<= r.end_range
group by concat(start_range, '-', end_range);
SELECT
-- NB this must match your group by statement exactly 
-- otherwise you will get an error
CASE 
    WHEN amount <= 100
    THEN '0-100'
    WHEN amount <= 200
    THEN '100-200'
    ELSE '201+'
END Amount,
COUNT(*)
FROM  
    transactions
GROUP BY
CASE 
    WHEN amount <= 100
    THEN '0-100'
    WHEN amount <= 200
    THEN '100-200'
    ELSE '201+'
END
SELECT 
AmountGrouping(amount),
COUNT(*)
FROM  
transactions
GROUP BY
AmountGrouping(amount)
SELECT
    concat(((amount DIV 100) * 100),'-',(((amount DIV 100) + 1) * 100)) AmountGroup,
    COUNT(*)
FROM  
    transactions
GROUP BY
    AmountGroup
DROP SCHEMA IF EXISTS `stackoverflow3`;
CREATE SCHEMA `stackoverflow3`;
USE `stackoverflow3`;

CREATE TABLE users (
  id INT UNSIGNED PRIMARY KEY NOT NULL AUTO_INCREMENT,
  name VARCHAR(25) NOT NULL DEFAULT "-");

CREATE TABLE transactions(
  id INT UNSIGNED PRIMARY KEY NOT NULL AUTO_INCREMENT,
  user_id INT UNSIGNED NOT NULL,
  amount INT UNSIGNED DEFAULT 0,
  FOREIGN KEY (user_id) REFERENCES users (id));

INSERT users () VALUES (),(),();
INSERT transactions (user_id,amount)
  VALUES (1,120),(2,270),(3, 350),
    (2,500), (1,599), (1,550), (3,10),
    (3,20), (3,30), (3,50), (3,750);

SELECT
  COUNT(t.id),
  CONCAT(
    ((t.amount DIV 100)*100)," to ",((t.amount DIV 100 + 1)*100-1)
  ) AS amount_range
FROM transactions AS t
GROUP BY amount_range;