typora-copy-images-to: asset


Spark SQL

Spark SQL概述

Spark SQL进化之路

1.0以前: Shark
1.1.x开始:SparkSQL(只是测试性的) SQL
1.3.x: SparkSQL(正式版本)+Dataframe
1.5.x: SparkSQL 钨丝计划(Tungsten) 聚焦于CPU和Memory使用,以达到对分布式硬件潜能的终极压榨!
1.6.x: SparkSQL+DataFrame+DataSet(测试版本)
2.x:

  • SparkSQL+DataFrame+DataSet(正式版本)
  • SparkSQL:还有其他的优化
  • StructuredStreaming(DataSet)

认识Spark SQL

  • Spark SQL是Spark的一个模块,主要用于进行结构化数据的处理。它提供的最核心的编程抽象就是DataFrame。
  • 作用:提供一个编程抽象(DataFrame) 并且作为分布式 SQL 查询引擎
  • 运行原理:将 Spark SQL 转化为 RDD, 然后提交到集群执行
  • 特性:
    • 集成。即:无缝地将SQL查询与Spark程序混合。
    • 统一数据访问。即:加载和查询来自各种来源的数据。包括Hive、Parquet、JSON和JDBC等。
    • Hive兼容性。即:在现有仓库上运行未修改的Hive查询。
    • 标准连接。即:通过JDBC或ODBC连接。

SparkSession

SparkSession是Spark 2.0引如的新概念。SparkSession为用户提供了统一的切入点,来让用户学习Spark的各项功能。

  • 在Spark的早期版本中,SparkContext是Spark的主要切入点,由于RDD是主要的API,我们通过SparkContext来创建和操作RDD。
  • 随着DataSet和DataFrame的API逐渐成为标准的API,就需要为他们建立接入点。
  • SparkSession作为DataSet和DataFrame API的切入点,SparkSession封装了SparkConf、SparkContext和SQLContext。

特点:

  • 为用户提供一个统一的切入点使用Spark 各项功能
  • 允许用户通过它调用 DataFrame 和 Dataset 相关 API 来编写程序
  • 减少了用户需要了解的一些概念,可以很容易的与 Spark 进行交互
  • 与 Spark 交互之时不需要显示的创建 SparkConf, SparkContext 以及 SQlContext,这些对象已经封闭在 SparkSession 中

DataFrame

在Spark中,DataFrame是一种以RDD为基础的分布式数据集,类似于传统数据库中的二维表格。

DataFrame与RDD的主要区别在于,前者带有schema元信息,即DataFrame所表示的二维表数据集的每一列都带有名称和类型。

创建DataFrame

  1. # 通过列表生成
  2. from pyspark.sql import SparkSession
  3. spark = SparkSession.builder.getOrCreate()
  4. data = [('zhangsan',18,'男'),('lisi',19,'男'),('wangwu',20,'女'),]
  5. df = spark.createDataFrame(data,['name','age','sex'])
  6. df.collect()
  7. """
  8. [Row(name='zhangsan', age=18, sex='男'),
  9. Row(name='lisi', age=19, sex='男'),
  10. Row(name='wangwu', age=20, sex='女')]
  11. """
  1. # 通过字典生成
  2. from pyspark.sql import SparkSession
  3. spark = SparkSession.builder.getOrCreate()
  4. data = [{"name":"zhangsan","age":18},{"name":"lisi","age":19}]
  5. df = spark.createDataFrame(data)
  6. df.collect()
  7. """[Row(age=18, name='zhangsan'), Row(age=19, name='lisi')]"""
  1. # 通过文件生成
  2. from pyspark.sql import SparkSession
  3. spark = SparkSession.builder.getOrCreate()
  4. df = spark.read.csv('person.csv',header=True)
  5. df.collect()
  6. """
  7. person.csv:
  8. name,age
  9. zhangsan,18
  10. lisi,19
  11. wangwu,20
  12. [Row(name='zhangsan', age='18'),
  13. Row(name='lisi', age='19'),
  14. Row(name='wangwu', age='20')]
  15. """
  1. # 通过pandas DataFrame生成
  2. import pandas as pd
  3. from pyspark.sql import SparkSession
  4. spark = SparkSession.builder.getOrCreate()
  5. data = pd.DataFrame({"name":"zhangsan","age":18},{"name":"lisi","age":19})
  6. df = spark.createDataFrame(data)
  7. df.collect()
  8. """
  9. [Row(name='zhangsan', age=18), Row(name='zhangsan', age=18)]
  10. """
  11. # 转为pandas中的DataFrame
  12. df.toPandas()
  13. """
  14. name age
  15. --------------------
  16. 0 zhangsan 18
  17. 1 zhangsan 18
  18. """
  1. # 通过RDD生成
  2. from pyspark.sql import SparkSession
  3. spark = SparkSession.builder.getOrCreate()
  4. # 生成RDD
  5. data = ["zhangsan,18","lisi,19","wangwu,20"]
  6. rdd = spark.sparkContext.parallelize(data).map(lambda x:x.split(","))
  7. rdd.collect()
  8. """
  9. [['zhangsan', '18'], ['lisi', '19'], ['wangwu', '20']]
  10. """
  11. # 用反射来推断包含特定类型对象的RDD的schema
  12. from pyspark.sql.types import Row
  13. def func(x):
  14. rel = {}
  15. rel['name'] = x[0]
  16. rel['age'] = int(x[1])
  17. return rel
  18. df = rdd.map(lambda x:Row(**func(x))).toDF()
  19. df.collect()
  20. """
  21. [Row(age=18, name='zhangsan'),
  22. Row(age=19, name='lisi'),
  23. Row(age=20, name='wangwu')]
  24. """
  25. df.schema
  26. """
  27. StructType(List(StructField(age,LongType,true),StructField(name,StringType,true)))
  28. """
  29. # 使用编程接口
  30. from pyspark.sql.types import StructType
  31. from pyspark.sql.types import StructField
  32. from pyspark.sql.types import StringType
  33. from pyspark.sql.types import LongType
  34. rdd = rdd.map(lambda x:(x[0],int(x[1])))
  35. schema = StructType([
  36. StructField('name',StringType(),True),
  37. StructField('age',LongType(),True),
  38. ])
  39. df = spark.createDataFrame(rdd,schema=schema)
  40. df.collect()
  41. """
  42. [Row(name='zhangsan', age=18),
  43. Row(name='lisi', age=19),
  44. Row(name='wangwu', age=20)]
  45. """
  46. # 简化版本
  47. df = spark.createDataFrame(rdd,['name','age'])
  48. df.collect()
  49. """
  50. [Row(name='zhangsan', age=18),
  51. Row(name='lisi', age=19),
  52. Row(name='wangwu', age=20)]
  53. """
  54. df.schema
  55. """
  56. StructType(List(StructField(name,StringType,true),StructField(age,LongType,true)))
  57. """
  58. # 最简版本
  59. df = rdd.toDF(['name','age'])
  60. df.collect()
  61. # DataFrame转为RDD
  62. df.rdd

创建Spark SQL

  • Spark SQL 是由DataFrame派生出来的,首先必须先出创建DataFrame,然后通过登录Spark SQL temp table就可以使用Spark SQL语句了。
  • 使用Spark SQL最简单,就是直接使用SQL语句,即使是非程序设计人员,只需要懂得SQL语句就可以使用
  1. from pyspark.sql import SparkSession
  2. spark = SparkSession.builder.getOrCreate()
  3. data = ["zhangsan,18","lisi,19","wangwu,20"]
  4. rdd = spark.sparkContext.parallelize(data).map(lambda x:x.split(","))
  5. rdd = rdd.map(lambda x:(x[0],int(x[1])))
  6. df = rdd.toDF(['name','age'])
  7. # 方式一 SQL 通过createOrReplaceTempView注册为
  8. df.createOrReplaceTempView('person1')
  9. res = spark.sql("select * from person1 where age > 18")
  10. res.collect()
  11. """
  12. [Row(name='lisi', age=19), Row(name='wangwu', age=20)]
  13. """
  14. # 方式二 SQL 通过registerTempTable注册
  15. df.registerTempTable('person2')
  16. res = spark.sql("select * from person2 where age > 18")
  17. res.collect()
  18. # 方式三 DSL
  19. df.filter("age > 18").collect()

Spark SQL实验二

实验数据

emp.csv

  1. emp_num,emp_name,role,leader_num,birth_date,salary,bonus,dept_num
  2. 7369,SMITH,CLERK,7902,1980/12/17,800,,20
  3. 7499,ALLEN,SALESMAN,7698,1981/2/20,1600,300,30
  4. 7521,WARD,SALESMAN,7698,1981/2/22,1250,500,30
  5. 7566,JONES,MANAGER,7839,1981/4/2,2975,,20
  6. 7654,MARTIN,SALESMAN,7698,1981/9/28,1250,1400,30
  7. 7698,BLAKE,MANAGER,7839,1981/5/1,2850,,30
  8. 7782,CLARK,MANAGER,7839,1981/6/9,2450,,10
  9. 7788,SCOTT,ANALYST,7566,1987/4/19,3000,,20
  10. 7839,KING,PRESIDENT,,1981/11/17,5000,,10
  11. 7844,TURNER,SALESMAN,7698,1981/9/8,1500,0,30
  12. 7876,ADAMS,CLERK,7788,1987/5/23,1100,,20
  13. 7900,JAMES,CLERK,7698,1981/12/3,950,,30
  14. 7902,FORD,ANALYST,7566,1981/12/3,3000,,20
  15. 7934,MILLER,CLERK,7782,1982/1/23,1300,,10

实验要求

使用DataFrame相关方法完成实验

实验内容

  1. # 初始化SparkSession
  2. from pyspark.sql import SparkSession
  3. spark = SparkSession.builder.getOrCreate()
  1. 读取emp.csv文件,获取DataFrame
    1. emp = spark.read.csv("emp.csv",header=True)
    2. emp.show() # show默认展示前20条数据
  1. 将salary、bonus列改为整型
    1. import pyspark.sql.functions as F
    2. from pyspark.sql.types import *
  1. 找出所有奖金(bonus)不为空的人员名单 ```python

    方式一 registerTempTable

    emp.registerTempTable(“emp”)

方式二 createOrReplaceTempView

emp.createOrReplaceTempView(“emp”)

  1. <br />spark.sql("select * from emp where bonus is not null").show() <br />+-------+--------+--------+----------+---------+------+-----+--------+<br />|emp_num|emp_name| role|leader_num| hiredate|salary|bonus|dept_num|<br />+-------+--------+--------+----------+---------+------+-----+--------+<br />| 7499| ALLEN|SALESMAN| 7698|1981/2/20| 1600| 300| 30|<br />| 7521| WARD|SALESMAN| 7698|1981/2/22| 1250| 500| 30|<br />| 7654| MARTIN|SALESMAN| 7698|1981/9/28| 1250| 1400| 30|<br />| 7844| TURNER|SALESMAN| 7698| 1981/9/8| 1500| 0| 30|<br />+-------+--------+--------+----------+---------+------+-----+--------+
  2. <a name="SQL"></a>
  3. # SQL
  4. 4. 新增一列总薪资(total),其值为薪资(salary)和奖金(bonus)的总和
  5. ```python
  6. # DataFrame
  7. emp.selectExpr("*","if(bonus is null,salary,salary+bonus) as total").show()
  8. #SQL
  9. spark.sql("select *,if(bonus is null,salary,salary+bonus) as total from emp").show()
  10. #F.udf
  11. @F.udf(returnType=IntegerType())
  12. def get_total(x,y):
  13. if y is None:
  14. return x
  15. else:
  16. return x+y
  17. emp.select("*",get_total(F.col("salary"),F.col("bonus")).alias("total")).show()
  18. emp.select("*",get_total("salary","bonus").alias("total")).show()


  1. 新增age,其值为该员工年龄(2022-birth_date) ```python

    DataFrame

    emp.selectExpr(“*”,”2022 - cast(substring(birth_date,0,4) as int) as age”).show()

SQL

spark.sql(“select *,2022 - cast(substring(birth_date,0,4) as int) as age from emp”).show()

F.udf

@F.udf(returnType=IntegerType()) def get_age(x): year = int(x[:4]) return 2022 - year emp.select(“*”,get_age(“birth_date”).alias(“age”)).show()

  1. 6. 统计各岗位(role)人数
  2. ```python
  3. # DataFrame
  4. emp.groupby("role").count().show()
  5. # SQL
  6. spark.sql("select role,count(1) num from emp group by role").show()
  1. 计算各部门平均薪资(total),保留两位小数,按平均薪资降序排序 ```python

    DataFrame

    emp.groupby(“dept_num”).agg(F.round(F.mean(“total”),2).alias(“mean_total”)).sort(F.col(“mean_total”).desc()).show()

SQL

spark.sql(“select dept_num,round(avg(total),2) as mean_total from emp group by dept_num order by mean_total desc”)

F.udf

  1. 8. 找出各部门总薪资(total)最高的员工
  2. ```python
  3. # DataFrame
  4. emp.select("*",F.row_number().over(Window.partitionBy("dept_num").orderBy(F.col("total").desc())).alias("rn")).filter("rn = 1").show()
  5. # SQL
  6. spark.sql("select * from (select *,row_number() over(partition by dept_num order by total desc) as rn from emp) a where a.rn = 1").show()

SparkSQL实验三

实验内容

  1. 读取book文件,生成RDD
    1. ('5173', '動力取向精神醫學--臨床應用與實務', 10.0, '1200元', '心灵工坊', 'https://book.douban.com/subject/6053667/')
    2. ('9929', '水彩绘森活', 10.0, '29.8', '人民邮电出版社', 'https://book.douban.com/subject/26115807/')
    3. ('10124', '殷周金文集成(修订增补本共8册)(精)', 10.0, '2400.00元', '中华书局', 'https://book.douban.com/subject/2235855/')
    4. ('16628', '纸雕游戏大书', 10.0, '99.00元', '重庆出版集团', 'https://book.douban.com/subject/26673804/')
    5. ('19103', 'Michelangelo', 10.0, '$200.00 ', 'Taschen', 'https://book.douban.com/subject/2342660/')
    6. ('20063', '一支笔的快乐涂鸦2', 10.0, '29.8', '人民邮电出版社', 'https://book.douban.com/subject/26280062/')
    7. ('32781', '亲亲宝贝装', 10.0, '28.00元', '江西科学技术出版社', 'https://book.douban.com/subject/20429352/')
    8. ('32879', 'Photoshop7解像', 10.0, '68.00元', '海洋出版社', 'https://book.douban.com/subject/1244906/')
    9. ('45687', '戚蓼生序本石头记', 10.0, '350.00元', '人民文学出版社', 'https://book.douban.com/subject/6751176/')
    10. ('52504', '宇宙兄弟(7)', 10.0, 'JPY580', '講談社', 'https://book.douban.com/subject/5407120/')
  1. 将RDD转为DataFrame(score列转为浮点型)
    1. +-----+-------------------+-----+--------+---------+--------------------+
    2. | id| name|score| price| pub| url|
    3. +-----+-------------------+-----+--------+---------+--------------------+
    4. | 5173| 動力取向精神醫學--臨床應用與實務| 10.0| 1200元| 心灵工坊|https://book.doub...|
    5. | 9929| 水彩绘森活| 10.0| 29.8| 人民邮电出版社|https://book.doub...|
    6. |10124|殷周金文集成(修订增补本共8册)(精)| 10.0|2400.00元| 中华书局|https://book.doub...|
    7. |16628| 纸雕游戏大书| 10.0| 99.00元| 重庆出版集团|https://book.doub...|
    8. |19103| Michelangelo| 10.0|$200.00 | Taschen|https://book.doub...|
    9. |20063| 一支笔的快乐涂鸦2| 10.0| 29.8| 人民邮电出版社|https://book.doub...|
    10. |32781| 亲亲宝贝装| 10.0| 28.00元|江西科学技术出版社|https://book.doub...|
    11. |32879| Photoshop7解像| 10.0| 68.00元| 海洋出版社|https://book.doub...|
    12. |45687| 戚蓼生序本石头记| 10.0| 350.00元| 人民文学出版社|https://book.doub...|
    13. |52504| 宇宙兄弟(7)| 10.0| JPY580| 講談社|https://book.doub...|
    14. +-----+-------------------+-----+--------+---------+--------------------+
  1. 将DataFrame注册为表,表名为:tb_book
  2. 使用SQL查询前10条数据
    1. +-----+-------------------+-----+--------+---------+--------------------+
    2. | id| name|score| price| pub| url|
    3. +-----+-------------------+-----+--------+---------+--------------------+
    4. | 5173| 動力取向精神醫學--臨床應用與實務| 10.0| 1200元| 心灵工坊|https://book.doub...|
    5. | 9929| 水彩绘森活| 10.0| 29.8| 人民邮电出版社|https://book.doub...|
    6. |10124|殷周金文集成(修订增补本共8册)(精)| 10.0|2400.00元| 中华书局|https://book.doub...|
    7. |16628| 纸雕游戏大书| 10.0| 99.00元| 重庆出版集团|https://book.doub...|
    8. |19103| Michelangelo| 10.0|$200.00 | Taschen|https://book.doub...|
    9. |20063| 一支笔的快乐涂鸦2| 10.0| 29.8| 人民邮电出版社|https://book.doub...|
    10. |32781| 亲亲宝贝装| 10.0| 28.00元|江西科学技术出版社|https://book.doub...|
    11. |32879| Photoshop7解像| 10.0| 68.00元| 海洋出版社|https://book.doub...|
    12. |45687| 戚蓼生序本石头记| 10.0| 350.00元| 人民文学出版社|https://book.doub...|
    13. |52504| 宇宙兄弟(7)| 10.0| JPY580| 講談社|https://book.doub...|
    14. +-----+-------------------+-----+--------+---------+--------------------+
  1. 使用SQL查询书名包含“微积分”的书
    1. +-----+---------------+-----+------+--------------------+--------------------+
    2. | id| name|score| price| pub| url|
    3. +-----+---------------+-----+------+--------------------+--------------------+
    4. | 5522| 微积分和数学分析引论-第1卷| 9.9|79.00元| 世界图书出版公司|https://book.doub...|
    5. | 2219| 微积分学教程(第3卷)| 9.6|53.00元| 高等教育出版社|https://book.doub...|
    6. | 2220| 微积分学教程(第2卷)| 9.4|65.00元| 高等教育出版社|https://book.doub...|
    7. | 2363| 微积分学教程(第一卷)| 9.4|45.00元| 高等教育出版社|https://book.doub...|
    8. | 1153| 微积分五讲| 9.3|14.00元| 科学出版社|https://book.doub...|
    9. | 1427|微积分和数学分析引论(第一卷)| 9.3|48.00元| 科学出版社|https://book.doub...|
    10. | 5526| 实用微积分| 9.3|89.00元| 人民邮电出版社|https://book.doub...|
    11. | 1447| 简明微积分| 9.2|37.90元| 高等教育|https://book.doub...|
    12. | 3587| 托马斯微积分| 9.2| 88| 高等教育出版社|https://book.doub...|
    13. | 1360| 重温微积分| 9.1|39.60元| 高等教育出版社|https://book.doub...|
    14. | 4767| 普林斯顿微积分读本| 9.1|95.00元| 人民邮电出版社|https://book.doub...|
    15. | 1925| 高等微积分| 9.0|68.00元|北京蓝色畅想图书发行有限公司(原高...|https://book.doub...|
    16. | 8293| 微积分(下册)| 9.0|43.80元| 高等教育出版社|https://book.doub...|
    17. | 5523| 微积分(上册)| 8.7|60.00元| 高等教育出版社|https://book.doub...|
    18. | 7305| 微积分之屠龙宝刀| 8.7|28.00元| 湖南科学技术出版社|https://book.doub...|
    19. |15469| 微积分之屠龙宝刀| 8.7|24.80元| 湖南科学技术出版社|https://book.doub...|
    20. | 5525| 微积分之倚天宝剑| 8.6|32.00元| 湖南科学技术出版社|https://book.doub...|
    21. |10812| 微积分之倚天宝剑| 8.6|25.00元| 湖南科学技术出版社|https://book.doub...|
    22. | 1097| 微积分的历程| 8.5|29.00元| 人民邮电出版社|https://book.doub...|
    23. | 3588| 微积分及其应用| 8.5|69.00元| 机械工业出版社|https://book.doub...|
    24. | 1126| 微积分和数学分析引论| 8.0|69.00元| 世界图书出版公司|https://book.doub...|
    25. | 1870| 微积分入门I| 7.9|39.00元| 人民邮电|https://book.doub...|
    26. | 2205| 微积分概念发展史| 7.9|28.00元| 复旦大学出版社|https://book.doub...|
    27. +-----+---------------+-----+------+--------------------+--------------------+
  1. 使用SQL查询图书的前10行的name和price字段信息
    1. +-------------------+--------+
    2. | name| price|
    3. +-------------------+--------+
    4. | 動力取向精神醫學--臨床應用與實務| 1200元|
    5. | 水彩绘森活| 29.8|
    6. |殷周金文集成(修订增补本共8册)(精)|2400.00元|
    7. | 纸雕游戏大书| 99.00元|
    8. | Michelangelo|$200.00 |
    9. | 一支笔的快乐涂鸦2| 29.8|
    10. | 亲亲宝贝装| 28.00元|
    11. | Photoshop7解像| 68.00元|
    12. | 戚蓼生序本石头记| 350.00元|
    13. | 宇宙兄弟(7)| JPY580|
    14. +-------------------+--------+
  1. 使用SQL统计书名包含“微积分”的书的数量
    1. +---+
    2. |num|
    3. +---+
    4. | 23|
    5. +---+
  1. 使用SQL查询评分大于9的图书,只展示前10条
    1. +-----+-------------------+-----+--------+---------+--------------------+
    2. | id| name|score| price| pub| url|
    3. +-----+-------------------+-----+--------+---------+--------------------+
    4. | 5173| 動力取向精神醫學--臨床應用與實務| 10.0| 1200元| 心灵工坊|https://book.doub...|
    5. | 9929| 水彩绘森活| 10.0| 29.8| 人民邮电出版社|https://book.doub...|
    6. |10124|殷周金文集成(修订增补本共8册)(精)| 10.0|2400.00元| 中华书局|https://book.doub...|
    7. |16628| 纸雕游戏大书| 10.0| 99.00元| 重庆出版集团|https://book.doub...|
    8. |19103| Michelangelo| 10.0|$200.00 | Taschen|https://book.doub...|
    9. |20063| 一支笔的快乐涂鸦2| 10.0| 29.8| 人民邮电出版社|https://book.doub...|
    10. |32781| 亲亲宝贝装| 10.0| 28.00元|江西科学技术出版社|https://book.doub...|
    11. |32879| Photoshop7解像| 10.0| 68.00元| 海洋出版社|https://book.doub...|
    12. |45687| 戚蓼生序本石头记| 10.0| 350.00元| 人民文学出版社|https://book.doub...|
    13. |52504| 宇宙兄弟(7)| 10.0| JPY580| 講談社|https://book.doub...|
    14. +-----+-------------------+-----+--------+---------+--------------------+
  1. 使用SQL计算所有书名包含“微积分”的评分平均值,保留两位小数
    1. +----------+
    2. |mean_score|
    3. +----------+
    4. | 8.91|
    5. +----------+
  1. 使用SQL把书目按照评分从高到低进行排列,且只展示前20条
  1. +-----+--------------------+-----+--------+------------------+--------------------+
  2. | id| name|score| price| pub| url|
  3. +-----+--------------------+-----+--------+------------------+--------------------+
  4. | 5173| 動力取向精神醫學--臨床應用與實務| 10.0| 1200元| 心灵工坊|https://book.doub...|
  5. | 9929| 水彩绘森活| 10.0| 29.8| 人民邮电出版社|https://book.doub...|
  6. |10124| 殷周金文集成(修订增补本共8册)(精)| 10.0|2400.00元| 中华书局|https://book.doub...|
  7. |16628| 纸雕游戏大书| 10.0| 99.00元| 重庆出版集团|https://book.doub...|
  8. |19103| Michelangelo| 10.0|$200.00 | Taschen|https://book.doub...|
  9. |20063| 一支笔的快乐涂鸦2| 10.0| 29.8| 人民邮电出版社|https://book.doub...|
  10. |32781| 亲亲宝贝装| 10.0| 28.00元| 江西科学技术出版社|https://book.doub...|
  11. |32879| Photoshop7解像| 10.0| 68.00元| 海洋出版社|https://book.doub...|
  12. |45687| 戚蓼生序本石头记| 10.0| 350.00元| 人民文学出版社|https://book.doub...|
  13. |52504| 宇宙兄弟(7)| 10.0| JPY580| 講談社|https://book.doub...|
  14. |52505| 宇宙兄弟(8)| 10.0| JPY580| 講談社|https://book.doub...|
  15. | 573| TCP\IP详解(卷1英文版)| 9.9| 45| 机械工业出版社|https://book.doub...|
  16. | 589|计算机程序设计艺术卷1:基本算法(...| 9.9| 119.00元| 人民邮电出版社|https://book.doub...|
  17. | 5522| 微积分和数学分析引论-第1卷| 9.9| 79.00元| 世界图书出版公司|https://book.doub...|
  18. | 5547|PrinciplesofNeura...| 9.9|$103.41 |McGraw-HillMedical|https://book.doub...|
  19. | 7443| 奈特人体神经解剖彩色图谱| 9.9| 138.00元| 人民卫生出版社|https://book.doub...|
  20. | 8703| 数学、科学和认识论| 9.9| 32.00元| 商务印书馆|https://book.doub...|
  21. | 9924| 零基础学素描| 9.9| 20元| 人民邮电出版社|https://book.doub...|
  22. | 9926| 黑白花意3300例超写实的花之绘| 9.9| 29.80元| 人民邮电出版社|https://book.doub...|
  23. | 9927| 黑白画意:经典植物手绘教程| 9.9| 29.80元| 人民邮电出版社|https://book.doub...|
  24. +-----+--------------------+-----+--------+------------------+--------------------+
  1. 使用SQL把图书按照出版社进行分组,统计图书总数大于500的出版社,按图书总数降序排列
    group by having order by desc
    1. +------------+----+
    2. | pub| num|
    3. +------------+----+
    4. | 人民文学出版社|1437|
    5. | 上海译文出版社|1426|
    6. | 中华书局|1278|
    7. | 东立出版社|1223|
    8. |生活·读书·新知三联书店|1105|
    9. | 北京大学出版社| 948|
    10. | 译林出版社| 934|
    11. | 商务印书馆| 917|
    12. | 上海人民出版社| 829|
    13. | 广西师范大学出版社| 726|
    14. | 中国人民大学出版社| 641|
    15. | 人民邮电出版社| 599|
    16. | 上海古籍出版社| 590|
    17. | 南海出版公司| 575|
    18. | 尖端出版社| 557|
    19. | 中信出版社| 537|
    20. | 机械工业出版社| 519|
    21. | 新星出版社| 511|
    22. +------------+----+