分组_分组查询 - CSDN
精华内容
参与话题
  • Group by 分组详解

    千次阅读 2018-11-22 16:25:16
    先来看下表1,表名为test:   表1  执行如下SQL语句: 1 ...  你应该很容易知道运行的结果,没错,就是下表2: ... 可是为了能够更好的理解“group by”多个列“和”聚合函数“的应用,我建议在思考的过程中...

    先来看下表1,表名为test:

     

    表1

      执行如下SQL语句:

    1

    2

    SELECT name FROM test

    GROUP BY name

      你应该很容易知道运行的结果,没错,就是下表2:

     

    表2

      可是为了能够更好的理解“group by”多个列“”聚合函数“的应用,我建议在思考的过程中,由表1到表2的过程中,增加一个虚构的中间表:虚拟表3。下面说说如何来思考上面SQL语句执行情况:

    1.FROM test:该句执行后,应该结果和表1一样,就是原来的表。

    2.FROM test Group BY name:该句执行后,我们想象生成了虚拟表3,如下所图所示,生成过程是这样的:group by name,那么找name那一列,具有相同name值的行,合并成一行,如对于name值为aa的,那么<1 aa 2>与<2 aa 3>两行合并成1行,所有的id值和number值写到一个单元格里面。

     

    3.接下来就要针对虚拟表3执行Select语句了:

    (1)如果执行select *的话,那么返回的结果应该是虚拟表3,可是id和number中有的单元格里面的内容是多个值的,而关系数据库就是基于关系的,单元格中是不允许有多个值的,所以你看,执行select * 语句就报错了。

    (2)我们再看name列,每个单元格只有一个数据,所以我们select name的话,就没有问题了。为什么name列每个单元格只有一个值呢,因为我们就是用name列来group by的。

    (3)那么对于id和number里面的单元格有多个数据的情况怎么办呢?答案就是用聚合函数,聚合函数就用来输入多个数据,输出一个数据的。如cout(id),sum(number),而每个聚合函数的输入就是每一个多数据的单元格。

    (4)例如我们执行select name,sum(number) from test group by name,那么sum就对虚拟表3的number列的每个单元格进行sum操作,例如对name为aa的那一行的number列执行sum操作,即2+3,返回5,最后执行结果如下:

     (5)group by 多个字段该怎么理解呢:如group by name,number,我们可以把name和number 看成一个整体字段,以他们整体来进行分组的。如下图

    (6)接下来就可以配合select和聚合函数进行操作了。如执行select name,sum(id) from test group by name,number,结果如下图:

    (已失效)文章出处:理解group by和聚合函数

    注意:mysql对group by 进行了非ANSI标准的扩展,允许select后含有非group by 的列。

    展开全文
  • 深入理解sql分组查询(group by)

    万次阅读 2020-10-12 17:31:00
    理解group by语义个人认为sql中的group by和join是两大难点,因为它们...分组是聚合的前提,聚合是在每个分组内进行一些统计,如在分组内的最大值,最小值,平均值,个数等。未分组时查询返回的行直接与数据库表中的...

    理解group by语义

    个人认为sql中的group by和join是两大难点,因为它们转换了原来的表结构,group把表按某些字段统计缩小,join则使用笛卡尔积将多个表连接展开(关于表的连接,请参看深入理解SQL表连接(join),这篇文章以一个非常有趣的角度,带你彻底理解SQL表连接的本质)

    咱们回到group by,顾名思义group即为分组,即将原来的一整块数据分成几小块。分组是聚合的前提,聚合是在每个分组内进行一些统计,如在分组内的最大值,最小值,平均值,个数等。

    未分组时查询返回的行直接与数据库表中的行对应,分组后分为多少组这个查询就会返回多少条记录,返回的记录中只能包含分组字段和在这个分组上的聚合操作的值(MySQL是例外见后面)

    一般形式为:语法为:select t.sex, count(t.id) as cnt group by sex having cnt>2
    查询中有三种字段:
    查询字段:在select中出现的表中的字段
    聚合字段:对表中的字段施加了聚合函数后形成的字段
    分组字段:group by后的字段
     

    无分组字段时

    sql允许无分组字段,即无group by直接在select中用各种聚合函数,这时表示整块数据为一个分组(单分组),聚合操作则是在整块全局上进行聚合,表示为本查询中所有记录的最大值,最小值,平均值,个数等
    如果没有分组字段的聚合,则select后的字段只能全部都是带聚合的,不能直接是字段名否则Orcle会报错:ORA-00937: not a single-group group function(MySQL是个例外后面详述)
     

    MySQL的坑

    MySQL有一个让人不解的地方:在聚合查询中select可以出现非分组字段,语义上group by后的结果已经进行了分组变换,此时的数据均应对应于分组而不再是原表记录,在一个分组语义的记录里加入一个表的字段,语义上不太严谨,实际上MySQL会将非分组字段随便取一个值,不得不说算一个坑
    比如下面的查询Oracle报错而MySQL不报错
    select id, count(t.id) from
    (
    select 1 as id, 2 as age, 'F' as sex from dual union
    select 2 as id, 2 as age, 'M' as sex from dual union
    select 3 as id, 3 as age, 'F' as sex from dual union
    select 4 as id, 4 as age, 'M' as sex from dual 
    )t
    在MySQL中返回
    1 4
    该查询是单分组查询,4是总的记录条数没有问题,此时1是什么意思呢?它和计数有什么关系呢?

    *MySQL后面意识到这会导致很多潜在的问题,因此在高版本中对此问题进行了修复,即不再允许在select中出现非group的字段

     

    对null的处理

    count(*)统计包含null在内的行数,count后面跟上字段名则表示统计这个字段非null的行数

    聚合函数后面可以跟一个复合表达式,如多个字段相加,复合时如果其中一个字段为null则整个表达式为null,比如统计两个字段都非null的行数,可以count(f1+f2)

    count,avg,sum后面跟上字段名时如果为null值将会忽略,比如计算平均值时null的那一行并不会记入总行数

    如果带有group by则select后的字段要么是分组字段要么是聚合字段(MySQL仍然可以出现非分组字段)
     

    关于having

    与where不同的是having在group后进行进行过滤,where在group前进行过滤其写在group关键字前,having后过滤的字段可以是分组字段或聚合字段如:
    select sex, count(*) as cnt having sex='F'
    select sex, count(*) as cnt having cnt>1
     

    小技巧

    有时需要测试sql语法但又觉得创建表麻烦,可以使用创建一个临时表,如下:
    select id, count(t.id) from
    (
    select 1 as id, 2 as age, 'F' as sex from dual union
    select 2 as id, 2 as age, 'M' as sex from dual union
    select 3 as id, 3 as age, 'F' as sex from dual union
    select 4 as id, 4 as age, 'M' as sex from dual 
    )t

    展开全文
  • 分组查询

    千次阅读 2018-06-19 18:50:16
    特点:1、和分组函数一同查询的字段必须是group by后出现的字段2、筛选分为两类:分组前筛选和分组后筛选 针对的表 位置 连接的关键字分组前筛选 原始表 group by前 where 分组后筛选 group by后的结果集  ....


    #进阶5:分组查询


    /*
    语法:


    select 查询列表
    from 表
    【where 筛选条件】
    group by 分组的字段
    【order by 排序的字段】;


    特点:
    1、和分组函数一同查询的字段必须是group by后出现的字段
    2、筛选分为两类:分组前筛选和分组后筛选
    针对的表 位置 连接的关键字
    分组前筛选 原始表 group by前 where

    分组后筛选 group by后的结果集    group by后 having


    问题1:分组函数做筛选能不能放在where后面
    答:不能


    问题2:where——group by——having


    一般来讲,能用分组前筛选的,尽量使用分组前筛选,提高效率


    3、分组可以按单个字段也可以按多个字段
    4、可以搭配着排序使用








    */






    #引入:查询每个部门的员工个数


    SELECT COUNT(*) FROM employees WHERE department_id=90;
    #1.简单的分组


    #案例1:查询每个工种的员工平均工资
    SELECT AVG(salary),job_id
    FROM employees
    GROUP BY job_id;


    #案例2:查询每个位置的部门个数


    SELECT COUNT(*),location_id
    FROM departments
    GROUP BY location_id;




    #2、可以实现分组前的筛选


    #案例1:查询邮箱中包含a字符的 每个部门的最高工资


    SELECT MAX(salary),department_id
    FROM employees
    WHERE email LIKE '%a%'
    GROUP BY department_id;




    #案例2:查询有奖金的每个领导手下员工的平均工资


    SELECT AVG(salary),manager_id
    FROM employees
    WHERE commission_pct IS NOT NULL
    GROUP BY manager_id;






    #3、分组后筛选


    #案例:查询哪个部门的员工个数>5


    #①查询每个部门的员工个数
    SELECT COUNT(*),department_id
    FROM employees
    GROUP BY department_id;


    #② 筛选刚才①结果


    SELECT COUNT(*),department_id
    FROM employees


    GROUP BY department_id


    HAVING COUNT(*)>5;




    #案例2:每个工种有奖金的员工的最高工资>12000的工种编号和最高工资


    SELECT job_id,MAX(salary)
    FROM employees
    WHERE commission_pct IS NOT NULL
    GROUP BY job_id
    HAVING MAX(salary)>12000;




    #案例3:领导编号>102的每个领导手下的最低工资大于5000的领导编号和最低工资


    manager_id>102


    SELECT manager_id,MIN(salary)
    FROM employees
    GROUP BY manager_id
    HAVING MIN(salary)>5000;




    #4.添加排序


    #案例:每个工种有奖金的员工的最高工资>6000的工种编号和最高工资,按最高工资升序


    SELECT job_id,MAX(salary) m
    FROM employees
    WHERE commission_pct IS NOT NULL
    GROUP BY job_id
    HAVING m>6000
    ORDER BY m ;








    #5.按多个字段分组


    #案例:查询每个工种每个部门的最低工资,并按最低工资降序


    SELECT MIN(salary),job_id,department_id
    FROM employees
    GROUP BY department_id,job_id
    ORDER BY MIN(salary) DESC;













    展开全文
  • 分组

    2019-07-13 22:53:42
    题目描述 小 C 在了解了她所需要的信息之后,让兔子们调整到了恰当的位置。小 C 准备给兔子 们分成若干个小组来喂...在分组前,小 C 发现了一个规律:有些兔子会两两发生矛盾。并且,两只兔子会发生矛 盾,当且仅当...

    题目描述

    小 C 在了解了她所需要的信息之后,让兔子们调整到了恰当的位置。小 C 准备给兔子 们分成若干个小组来喂恰当的胡萝卜给兔子们吃。

    此时, nnn 只兔子按一定顺序排成一排,第 iii 只兔子的颜色是 aia_iai 。由于顺序已经是被 调整好了的,所以每个小组都应当是序列上连续的一段。

    在分组前,小 C 发现了一个规律:有些兔子会两两发生矛盾。并且,两只兔子会发生矛 盾,当且仅当代表他们的颜色的数值之和为一个正整数的平方。比如,1 色兔子和 2 色兔子 不会发生矛盾,因为 3 不是任何一个正整数的平方;而 1 色兔子却会和 3 色兔子发生矛盾, 因为 4=224 = 2^24=22。

    小 C 认为,只要一个小组内的矛盾不要过大就行。因此,小 C 定义了一个小组的矛盾 值 kkk ,表示在这个小组里,至少需要将这个组再一次分成 kkk 个小团体;每个小团体并不需 要是序列上连续的一段,但是需要使得每个小团体内任意两只兔子之间都不会发生矛盾。

    小 C 要求,矛盾值最大的小组的矛盾值 kkk 不超过 KKK 就可以了。当然,这样的分组方 法可能会有很多个;为了使得分组变得更加和谐,小 C 想知道,在保证分组数量最少的情况 下,字典序最小的方案是什么。你能帮帮她吗?

    字典序最小的方案是指,按顺序排列分组的间隔位置,即所有存在兔子 iii 和 i+1i + 1i+1 在 不同组的位置 iii,和其它所有相同分组组数相同的可行方案相比总有第一个不同的位置比其 它方案小的方案。

    输入输出格式

    输入格式:

    从标准输入中读入数据。

    输入第 1 行两个正整数 n,Kn,Kn,K。

    输入第 2 行 nnn 个正整数,第 iii 个数表示第 iii 只兔子的颜色 aia_iai

    输出格式:

    输出到标准输出中。

    输出第 1 行一个正整数 mmm,为你至少需要将兔子分为多少个小组。

    输出第 2 行m−1m-1m1个从小到大的排列的正整数,第 iii 个数 sis_isi 表示 sis_isisi+1s_i + 1si+1 在 你的方案里被分到了两个小组。如果 m=1m = 1m=1,那么请输出一个空行。

    输入输出样例

    输入样例#1: 复制
    5 2 
    1 3 15 10 6
    输出样例#1: 复制
    2
    1 

    说明

    【样例 1 解释】

    如果将五只兔子全部分到同一个小组的话,那么 (1, 3) (3, 6) (6, 10) (10, 15) (1, 15) 均 不能分到同一个小团体;因为最多分成两个小团体,所以为了满足前 4 对限制,只能分为 {{1, 6, 15}, {3, 10}},但此时不满足 (1, 15) ,所以不存在一种组数为 1 的方案满足全部限制。

    如果将五只兔子分为两个小组的话,一种字典序最小的可行的分组方案是 {1}, {3, 15, 10, 6},此时第二组内的小团体数量不超过 2 的一种分法是 {{3, 10}, {15, 6}}。

    【数据范围】

    子任务会给出部分测试数据的特点。如果你在解决题目中遇到了困难,可以尝试只解 决一部分测试数据。

    每个测试点的数据规模及特点如下表:

    特殊性质 1:保证最优分组方案唯一。

    特殊性质 2:保证不会有两只相同颜色的兔子。

    从后向前选,能多选就多选,

     

    理由:数字越少肯定越优,同时间隔尽量向前推,字典序尽量小

    当k=1时很简单,直接走一边,每次枚举1~512判断,看是否存在x^2-a[i]的值

    当k=2时,每一组可以分两组,那么要出现i无法分配的情况

    那只能是a[i]+a[j]=x^2,a[i]+a[k]=y^2   a[j]+a[k]=z^2

    即j和k不能分一起,i也不能放在j或k在的一组

    于是用镜像并查集

    如果满足条件,那么i和j不能放一起,于是可以理解为i+n和j不可以放一起,i和j+n不可以放一起

    如果出现了如上情况,那么就会出现i和k+n,k都不能放一起,也就是i和k属同一个集合

     

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<vector>
      6 using namespace std;
      7 int set[400001],p[1001],a[400001],vis[400001],cnt,n,k;
      8 vector<int>map[400001];
      9 vector<int>v;
     10 vector<int>ans;
     11 int find(int x)
     12 {
     13   if (set[x]!=x) set[x]=find(set[x]);
     14   return set[x];
     15 }
     16 bool pd(int x,int y)
     17 {
     18   if (find(x)==find(y)) return 1;
     19   return 0;
     20 }
     21 void add(int x,int y)
     22 {
     23   int p=find(x),q=find(y);
     24   if (p!=q)
     25       set[p]=q;
     26 }
     27 bool check1(int x)
     28 {int i;
     29   for (i=512;i>=1;i--)
     30     if (p[i]<=a[x]) return 1;
     31     else 
     32       {
     33     if (vis[p[i]-a[x]]&&vis[p[i]-a[x]]==cnt)
     34       return 0;
     35       }
     36   return 1;
     37 }
     38 bool check2(int x)
     39 {int i,j;
     40   for (i=512;i>=1;i--)
     41     if (p[i]<=a[x]) return 1;
     42     else 
     43       {
     44     if (vis[p[i]-a[x]]&&vis[p[i]-a[x]]==cnt)
     45       {
     46         for (j=0;j<map[p[i]-a[x]].size();j++)
     47           {
     48         if (pd(x,map[p[i]-a[x]][j]))
     49           return 0;
     50         add(x,map[p[i]-a[x]][j]+n);
     51         add(x+n,map[p[i]-a[x]][j]);
     52           }
     53       }
     54       }
     55   return 1;
     56 }
     57 void solve1()
     58 {int i;
     59   cnt=1;
     60   for (i=1;i<=512;i++)
     61     p[i]=i*i;
     62   for (i=1;i<=n;i++)
     63     scanf("%d",&a[i]);
     64   for (i=n;i>=1;i--)
     65     if (check1(i))
     66       {
     67     vis[a[i]]=cnt;
     68       }
     69     else 
     70       {
     71     cnt++;
     72     vis[a[i]]=cnt;
     73     v.push_back(i);
     74       }
     75   cout<<cnt<<endl;
     76   for (i=v.size()-1;i>=0;i--)
     77     printf("%d ",v[i]);
     78 }
     79 void solve2()
     80 {int i;
     81     cnt=1;
     82   for (i=1;i<=512;i++)
     83     p[i]=i*i;
     84   for (i=1;i<=n;i++)
     85     scanf("%d",&a[i]);
     86   for (i=1;i<=2*n;i++)
     87     set[i]=i;
     88   for (i=n;i>=1;i--)
     89     if (check2(i))
     90       {
     91     if (vis[a[i]]!=cnt)
     92       vis[a[i]]=cnt,map[a[i]].clear();
     93     map[a[i]].push_back(i);
     94       }
     95     else 
     96       {
     97     cnt++;
     98     vis[a[i]]=cnt;
     99     map[a[i]].clear();
    100     map[a[i]].push_back(i);
    101     ans.push_back(i);
    102       }
    103   cout<<cnt<<endl;
    104   for (i=ans.size()-1;i>=0;i--)
    105     printf("%d ",ans[i]);
    106 }
    107 int main()
    108 {
    109   cin>>n>>k;
    110   if (k==1)
    111     solve1();
    112   else solve2();
    113 }

     

    转载于:https://www.cnblogs.com/Y-E-T-I/p/7782308.html

    展开全文
  • 分组密码

    2020-08-19 15:01:40
    一、分组密码概述 ... ...顾名思义,分组密码是将明文信息编码表示后的二进制序列,划分为固定大小的块,每一块分别在...分组足够长,假设n为发分组长度,则分组代换表中的字母个数2n足够大才能避免穷举攻击。 秘钥长度足够长
  • LeetCode 1169. 查询无效交易

    千次阅读 多人点赞 2020-06-06 10:16:37
    1. 题目 如果出现下述两种情况,交易 可能无效: 交易金额超过 ¥1000 或者,它和另一个城市中同名的另一笔交易相隔不超过 60 分钟(包含 60 分钟整) 每个交易字符串 transactions[i] 由一些用逗号分隔的值组成,...
  • MySQL分组,并且组内再排序

    万次阅读 2018-09-22 19:27:23
    需求:按照类别category_id分组,并对每个分类按时间date排序 注意:group by 分组后只取每组的第一条数据,这不符合要求,分组后,要求每组的数据不减少 数据库:       sql: SELECT a.*, count(1) AS ...
  • select phone,count(order_id) as c from table_record group by phone order by c desc
  • Zookeeper的CP特性

    万次阅读 2020-09-19 15:43:04
    Oracle报错:不是单组分组函数解决 - Oracle数据库栏目 - 红黑联盟 http://www.2cto.com/database/201308/236571.html Oracle报错:不是单组分组函数解决 报错:不是单组分组函数 实例:select deptno,count...
  • Java8 stream根据字段分组并排序

    万次阅读 2019-12-03 10:20:31
    Java8 stream根据字段分组并排序 1.根据字符串类型日期分组,并按照日期升序排序,返回TreeMap<String,List>,map的key为字符串日期,value为list ArrayList<PlnexecutionRecord> records = ...
  • SQL SERVER 分组求和

    万次阅读 2016-02-26 11:01:55
    需求: 实现方式: SELECT A1,SUM(A2*A3) FROM A GROUP BY A1
  • 密码库LibTomCrypt学习记录——目录

    万次阅读 2019-03-08 11:52:21
    (0)LibTomCrypt简介 (1)分组密码算法——概述 (1.1)分组密码算法——算法描述子cipher_descriptor (1.2)分组密码算法——使用前注册算法register_cipher (1.3)分组密码算法——AES算法的函数和使用...
  • SQL分组查询,结果只取最新记录

    万次阅读 热门讨论 2018-10-11 17:10:57
    select a.* from (select * from TABLE order by create_time desc) a group by a.user_id 这里查询的是USER_ID相同的最新一条数据
  • SPSS数据分组

    万次阅读 2018-08-24 15:01:18
    SPSS数据分组 数据分组,根据分析目的将数值型数据进行等距或非等距分组,这个过程也称为数据离散化,一般用于查看分布,入消费分布、收入分布、年龄分布等 在SPSS中主要使用可视分箱来对数据分组操作,首先打开...
  • Mysql——分组查询

    万次阅读 2019-06-21 23:59:30
     在进行分组统计时会用到分组查询,比如按部门统计人数、按工种统计工资情况等。分组查询一定会使用到分组函数,也一定会用到group by子句。  Tip:   1️⃣在分组查询中,所有不是分组函数的查询字段都要...
  • oracle 先分组后获取每组最大值

    万次阅读 2016-08-24 17:37:05
    用户每次登陆都会向表中插入一个登录日期,现在需要获取最近N位登录的用户及登陆时间, 因此现根据用户进行分组,然后在求出每组中最大的日期SELECT
  • 怎样用EXCEL对数值型字段进行分组

    万次阅读 2018-09-01 15:57:33
    1、什么是数值分组? 这里说的数值分组是指对数值型字段,按照一定的依据重新分组生成新字段。 如图,表1是原始数据,在表1中添加一个辅助列“分组”就形成了表2.字段“分组”是根据字段“成绩”决定的。学生...
  • MySql按列分组然后求和

    万次阅读 多人点赞 2013-09-02 22:41:34
    表中中有很多记录,每个记录假设如下所示 TableName:Money Name Salary Date wang ...这时候需要按某一列的信息分组,然后求和另一列的信息 使用如下sql语句可以快速获得所需要的信息,例如:
  • sql分组排序语句顺序

    万次阅读 2018-05-08 09:39:47
    SQL语句中,如果有group by 和order by两个语句,是先分组还是先排序? 先进行分组处理。 Group By 和 Having, Where ,Order by这些关键字是按照如下顺序进行执行的:Where, Group By, Having, Order by。 ...
  • SQL实现分组排序和组内排序

    万次阅读 2017-05-01 09:58:11
    在对表做排序时,经常会遇到需要先按某一个列排序,再按这个列分组的统计值来对子组或者说其它列排序的需求,下面是一个典型案例实现的技术路径:利用Mysql find_in_set group_concatselect * from user order by ...
1 2 3 4 5 ... 20
收藏数 629,276
精华内容 251,710
关键字:

分组