当前位置:   article > 正文

力扣 sql_力扣sql

力扣sql

1.编写一个 SQL 查询,查找 Person 表中所有重复的电子邮箱。

select Email from Person group by Email having count(Email)>1;

2.某网站包含两个表,Customers 表和 Orders 表。编写一个 SQL 查询,找出所有从不订购任何东西的客户。

select c.name Customers from Customers c where c.id not in(select CustomerId from Orders);

3.写一个查询语句,返回一个客户列表,列表中客户的推荐人的编号都 不是 2。

select name from customer where ifnull(referee_id,0)!=2;

4.订单数最多的客户

5.销售员

表:SalesPerson(销售人员的姓名和 ID ,以及他们的工资、佣金率和雇佣日期。)
        Company(公司的名称和 ID ,以及公司所在的城市。)
        Orders(这包括公司的 ID 、销售人员的 ID 、订单日期和支付的金额。)


编写一个SQL查询,报告没有任何与名为 “RED” 的公司相关的订单的所有销售人员的姓名。

6.如何判断奇数

7.性别变更:

请你编写一个 SQL 查询来交换所有的 'f' 和 'm' (即,将所有 'f' 变为 'm' ,反之亦然),仅使用 单个 update 语句 ,且不产生中间临时表。

用case....when....then....else...end
1)update salary set sex= case sex when 'm' then 'f' else 'm' end;

用if
2)update salary set sex = if(sex = 'm', 'f', 'm');

用ascii
3)update salary set sex = char(ascii(sex) ^ ascii('m') ^ ascii('f'));
解析:每一个字母都对应一个 ascii ,使用 ascii() 就可以把字母转换成 ascii ,在利用异或,相同的数为 0, 0 和任何数进行异或都是那个数,再利用 char 将 ascii 码转换成字母
具体的步骤:
ascii('m') 为 109 , ascii('f') 为 102
ascii('m') ^ ascii('m') ^ ascii('f') ,所以转化成 109 ^ 109 ^ 102 , 109 和 109 异或为 0 , 0 和 102 异或为 102 ,在用 char(102) 得出结果为 m 。
ascii('f') ^ ascii('m') ^ ascii('f') ,所以转化成 102 ^ 109 ^ 102 ,可以交换下 109 和 102 的位置,所以 102 和 102 异或为 0 , 0 和 109 异或为 109 ,在用 char(109) 得出结果为 f 。

8.销售分析|||

编写一个SQL查询,报告2019年春季才售出的产品。即2019-01-012019-03-31(含)之间出售的商品。(注意有些商品可能在2019年春季售出,在其他时间也在售出,这种商品应该排除)

select p.product_id,p.product_name from product p join sales s on p.product_id=s.product_id group by p.product_id having min(sale_date)>='2019-01-01' and max(sale_date)<='2019-03-31';

9.查询近30天活跃的用户数

select activity_date day,count(distinct user_id) active_users from activity where datediff('2019-07-27',activity_date)>=0 and datediff('2019-07-27',activity_date)<30 group by activity_date; 

9.重新格式化部门表

部门表 Department

+---------------+---------+
| Column Name   | Type    |
+---------------+---------+
| id            | int     |
| revenue       | int     |
| month         | varchar |
+---------------+---------+
(id, month) 是表的联合主键。
这个表格有关于每个部门每月收入的信息。
月份(month)可以取下列值 ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]。

编写一个 SQL 查询来重新格式化表,使得新的表中有一个部门 id 列和一些对应 每个月 的收入(revenue)列。查询结果格式如下面的示例所示:

Department 表:
+------+---------+-------+
| id   | revenue | month |
+------+---------+-------+
| 1    | 8000    | Jan   |
| 2    | 9000    | Jan   |
| 3    | 10000   | Feb   |
| 1    | 7000    | Feb   |
| 1    | 6000    | Mar   |
+------+---------+-------+

查询得到的结果表:
+------+-------------+-------------+-------------+-----+-------------+
| id   | Jan_Revenue | Feb_Revenue | Mar_Revenue | ... | Dec_Revenue |
+------+-------------+-------------+-------------+-----+-------------+
| 1    | 8000        | 7000        | 6000        | ... | null        |
| 2    | 9000        | null        | null        | ... | null        |
| 3    | null        | 10000       | null        | ... | null        |
+------+-------------+-------------+-------------+-----+-------------+

注意,结果表有 13 列 (1个部门 id 列 + 12个月份的收入列)。

SQL语句:

group by id 会使department表按照id分组,生成一张虚拟表(假想中的表)如下:

  1. +------+---------+-------+
  2. | id | revenue | month |
  3. +------+---------+-------+
  4. | | 8000 | Jan |
  5. | 1 | 7000 | Feb |
  6. | | 6000 | Mar |
  7. +------+---------+-------+
  8. | 2 | 9000 | Jan |
  9. +------+---------+-------+
  10. | 3 | 10000 | Feb |
  11. +------+---------+-------+

在虚拟表中,所有id=1的revenue或者month数据都写在了同一个单元格中,如8000、7000、6000都是写在同一单元格内的。真正的表是不能这样写的,所以这种写法只存在于虚拟表中,帮助我们理解。


一个单元格中有多个数据时,case when只会提取当中的第一个数据。以case when month='Feb' then revenue end为例,当id=1时,它只会提取month对应单元格里的第一个数据,即Jan,它不等于Feb,所以找不到Feb对应的revenue,所以返回NULL。(可以试试把我上面答案里的sum()统统去掉,执行结果与预期不一样。错就错在当id=1时,Feb_Revenue和Mar_Revenue的值变成了NULL)。

那该如何解决单元格内含多个数据的情况呢?答案就是使用聚合函数,聚合函数就用来输入多个数据,输出一个数据的。如SUM()或MAX(),而每个聚合函数的输入就是每一个多数据的单元格。

以sum(case when month='Feb' then revenue end) 为例,当id=1时,它提取的Jan、Feb、Mar,从中找到了符合条件的Feb,并最终返回对应的revenue的值,即7000。

10.排名靠前的旅行者

写一段 SQL , 报告每个用户的旅行距离。返回的结果表单,以 travelled_distance 降序排列 ,如果有两个或者更多的用户旅行了相同的距离, 那么再以 name 升序排列 。

 if(表达式,a,b)  表达式为真返回a,为假返回b。

coalesce(表达式1,表达式2,...)
按照顺序首先执行表达式1,如果不为null则返回表达式1的结果,如果为null,则往下执行表达式2。以此类推。可以用于当返回值为null时的默认返回。

注意 group by 不能换成 group by name ,以为有重名的可能性。

 11.按日期分组销售产品

表 Activities

+-------------+---------+
| 列名         | 类型    |
+-------------+---------+
| sell_date   | date    |
| product     | varchar |
+-------------+---------+
此表没有主键,它可能包含重复项。
此表的每一行都包含产品名称和在市场上销售的日期。

编写一个 SQL 查询来查找每个日期、销售的不同产品的数量及其名称。
每个日期的销售产品名称应按词典序排列。
返回按 sell_date 排序的结果表。
查询结果格式如下例所示。

示例 1:

  1. 输入:
  2. Activities
表: +------------+-------------+ | sell_date | product | +------------+-------------+ | 2020-05-30 | Headphone | | 2020-06-01 | Pencil | | 2020-06-02 | Mask | | 2020-05-30 | Basketball | | 2020-06-01 | Bible | | 2020-06-02 | Mask | | 2020-05-30 | T-Shirt | +------------+-------------+ 输出: +------------+----------+------------------------------+ | sell_date | num_sold | products | +------------+----------+------------------------------+ | 2020-05-30 | 3 | Basketball,Headphone,T-shirt | | 2020-06-01 | 2 | Bible,Pencil | | 2020-06-02 | 1 | Mask | +------------+----------+------------------------------+ 解释: 对于2020-05-30,出售的物品是 (Headphone, Basketball, T-shirt),按词典序排列,并用逗号 ',' 分隔。 对于2020-06-01,出售的物品是 (Pencil, Bible),按词典序排列,并用逗号分隔。 对于2020-06-02,出售的物品是 (Mask),只需返回该物品名。

 SQL

 concat():功能:将多个字符串连接成一个字符串,语法:concat(str1, str2,...),返回结果为连接参数产生的字符串,如果有任何一个参数为null,则返回值为null。相当于拼接字符串。
concat(a,b) 输出 ab   concat(a, ',' ,b) 输出 a,b

group_concat()
1、功能:将group by产生的同一个分组中的值连接起来,返回一个字符串结果。
2、语法:group_concat( [distinct] 要连接的字段 [order by 排序字段 asc/desc ] [separator '分隔符'] )
说明:通过使用distinct可以排除重复值;如果希望对结果中的值进行排序,可以使用order by子句;separator是一个字符串值,缺省为一个逗号。

12.换某种疾病的患者

患者信息表: Patients

+--------------+---------+
| Column Name  | Type    |
+--------------+---------+
| patient_id   | int     |
| patient_name | varchar |
| conditions   | varchar |
+--------------+---------+
patient_id (患者 ID)是该表的主键。
'conditions' (疾病)包含 0 个或以上的疾病代码,以空格分隔。
这个表包含医院中患者的信息。

写一条 SQL 语句,查询患有 I 类糖尿病的患者 ID (patient_id)、患者姓名(patient_name)以及其患有的所有疾病代码(conditions)。I 类糖尿病的代码总是包含前缀 DIAB1 。

按 任意顺序 返回结果表。

查询结果格式如下示例所示。

示例 1:

  1. 输入:
  2. Patients表:
+------------+--------------+--------------+ | patient_id | patient_name | conditions | +------------+--------------+--------------+ | 1 | Daniel  | YFEV COUGH | | 2   | Alice |   | | 3   | Bob  | DIAB100 MYOP | | 4   | George  | ACNE DIAB100 | | 5   | Alain  | DIAB201  | +------------+--------------+--------------+ 输出: +------------+--------------+--------------+ | patient_id | patient_name | conditions | +------------+--------------+--------------+ | 3   | Bob  | DIAB100 MYOP | | 4   | George   | ACNE DIAB100 | +------------+--------------+--------------+ 解释:Bob 和 George 都患有代码以 DIAB1 开头的疾病。

SQL:select* from patients where conditions regexp "\\bDIAB1";

\\b       第一个\是转义字符,\b匹配单词的开始与结束

13.进店却未进行交易的顾客

表:Visits

+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| visit_id    | int     |
| customer_id | int     |
+-------------+---------+
visit_id 是该表的主键。
该表包含有关光临过购物中心的顾客的信息。

表:Transactions

+----------------+---------+
| Column Name    | Type    |
+----------------+---------+
| transaction_id | int     |
| visit_id       | int     |
| amount         | int     |
+----------------+---------+
transaction_id 是此表的主键。
此表包含 visit_id 期间进行的交易的信息。

有一些顾客可能光顾了购物中心但没有进行交易。请你编写一个 SQL 查询,来查找这些顾客的 ID ,以及他们只光顾不交易的次数。

返回以 任何顺序 排序的结果表。

查询结果格式如下例所示。

示例 1:

  1. 输入:
  2. Visits
+----------+-------------+ | visit_id | customer_id | +----------+-------------+ | 1 | 23 | | 2 | 9 | | 4 | 30 | | 5 | 54 | | 6 | 96 | | 7 | 54 | | 8 | 54 | +----------+-------------+ Transactions +----------------+----------+--------+ | transaction_id | visit_id | amount | +----------------+----------+--------+ | 2 | 5 | 310 | | 3 | 5 | 300 | | 9 | 5 | 200 | | 12 | 1 | 910 | | 13 | 2 | 970 | +----------------+----------+--------+ 输出: +-------------+----------------+ | customer_id | count_no_trans | +-------------+----------------+ | 54 | 2 | | 30 | 1 | | 96 | 1 | +-------------+----------------+ 解释: ID = 23 的顾客曾经逛过一次购物中心,并在 ID = 12 的访问期间进行了一笔交易。 ID = 9 的顾客曾经逛过一次购物中心,并在 ID = 13 的访问期间进行了一笔交易。 ID = 30 的顾客曾经去过购物中心,并且没有进行任何交易。 ID = 54 的顾客三度造访了购物中心。在 2 次访问中,他们没有进行任何交易,在 1 次访问中,他们进行了 3 次交易。 ID = 96 的顾客曾经去过购物中心,并且没有进行任何交易。 如我们所见,ID 为 30 和 96 的顾客一次没有进行任何交易就去了购物中心。顾客 54 也两次访问了购物中心并且没有进行任何交易。

SQL:select customer_id,count(customer_id) count_no_trans from visits v left join transactions t on v.visit_id=t.visit_id where amount is null group by customer_id;

14.大小写转换

编写一个 SQL 查询来修复名字,使得只有第一个字符是大写的,其余都是小写的。

select user_id, concat(upper(left(name,1)),lower(substring(name,2))) name from users order by user_id;

1 concat() 函数
CONCAT 可以将多个字符串拼接在一起。

2 left(str, length) 函数
从左开始截取字符串,length 是截取的长度。

3 upper(str) 与 lower(str)
UPPER(str) 将字符串中所有字符转为大写
LOWER(str) 将字符串中所有字符转为小写

4 substring(str, begin, end)
截取字符串,end 不写默认为空。
SUBSTRING(name, 2) 从第二个截取到末尾,注意并不是下标,就是第二个。

15.列转行

表:Products

+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| product_id  | int     |
| store1      | int     |
| store2      | int     |
| store3      | int     |
+-------------+---------+
这张表的主键是product_id(产品Id)。
每行存储了这一产品在不同商店store1, store2, store3的价格。
如果这一产品在商店里没有出售,则值将为null。

请你重构 Products 表,查询每个产品在不同商店的价格,使得输出的格式变为(product_id, store, price) 。如果这一产品在商店里没有出售,则不输出这一行。

输出结果表中的 顺序不作要求 。

查询输出格式请参考下面示例。

示例 1:

输入:
Products table:
+------------+--------+--------+--------+
| product_id | store1 | store2 | store3 |
+------------+--------+--------+--------+
| 0          | 95     | 100    | 105    |
| 1          | 70     | null   | 80     |
+------------+--------+--------+--------+
输出:
+------------+--------+-------+
| product_id | store  | price |
+------------+--------+-------+
| 0          | store1 | 95    |
| 0          | store2 | 100   |
| 0          | store3 | 105   |
| 1          | store1 | 70    |
| 1          | store3 | 80    |
+------------+--------+-------+
解释:
产品0在store1,store2,store3的价格分别为95,100,105。
产品1在store1,store3的价格分别为70,80。在store2无法买到。

SQL

1. 列转行, 不考虑去重:union all, 考虑去重,用union 

2. 行转列: case when(sum+if)

16.计算特殊奖金

表: Employees

+-------------+---------+
| 列名        | 类型     |
+-------------+---------+
| employee_id | int     |
| name        | varchar |
| salary      | int     |
+-------------+---------+
employee_id 是这个表的主键。
此表的每一行给出了雇员id ,名字和薪水。

写出一个SQL 查询语句,计算每个雇员的奖金。如果一个雇员的id是奇数并且他的名字不是以'M'开头,那么他的奖金是他工资的100%,否则奖金为0。

Return the result table ordered by employee_id.

返回的结果集请按照employee_id排序。

查询结果格式如下面的例子所示。

示例 1:

输入:
Employees 表:
+-------------+---------+--------+
| employee_id | name    | salary |
+-------------+---------+--------+
| 2           | Meir    | 3000   |
| 3           | Michael | 3800   |
| 7           | Addilyn | 7400   |
| 8           | Juan    | 6100   |
| 9           | Kannon  | 7700   |
+-------------+---------+--------+
输出:
+-------------+-------+
| employee_id | bonus |
+-------------+-------+
| 2           | 0     |
| 3           | 0     |
| 7           | 7400  |
| 8           | 0     |
| 9           | 7700  |
+-------------+-------+
解释:
因为雇员id是偶数,所以雇员id 是2和8的两个雇员得到的奖金是0。
雇员id为3的因为他的名字以'M'开头,所以,奖金是0。
其他的雇员得到了百分之百的奖金。

SQL:

 17.2020年最后一次登

表: Logins

+----------------+----------+
| 列名           | 类型      |
+----------------+----------+
| user_id        | int      |
| time_stamp     | datetime |
+----------------+----------+
(user_id, time_stamp) 是这个表的主键。
每一行包含的信息是user_id 这个用户的登录时间。

编写一个 SQL 查询,该查询可以获取在 2020 年登录过的所有用户的本年度 最后一次 登录时间。结果集  包含 2020 年没有登录过的用户。

返回的结果集可以按 任意顺序 排列。

查询结果格式如下例。

示例 1:

输入:
Logins 表:
+---------+---------------------+
| user_id | time_stamp          |
+---------+---------------------+
| 6       | 2020-06-30 15:06:07 |
| 6       | 2021-04-21 14:06:06 |
| 6       | 2019-03-07 00:18:15 |
| 8       | 2020-02-01 05:10:53 |
| 8       | 2020-12-30 00:46:50 |
| 2       | 2020-01-16 02:49:50 |
| 2       | 2019-08-25 07:59:08 |
| 14      | 2019-07-14 09:00:00 |
| 14      | 2021-01-06 11:59:59 |
+---------+---------------------+
输出:
+---------+---------------------+
| user_id | last_stamp          |
+---------+---------------------+
| 6       | 2020-06-30 15:06:07 |
| 8       | 2020-12-30 00:46:50 |
| 2       | 2020-01-16 02:49:50 |
+---------+---------------------+
解释:
6号用户登录了3次,但是在2020年仅有一次,所以结果集应包含此次登录。
8号用户在2020年登录了2次,一次在2月,一次在12月,所以,结果集应该包含12月的这次登录。
2号用户登录了2次,但是在2020年仅有一次,所以结果集应包含此次登录。
14号用户在2020年没有登录,所以结果集不应包含。

SQL:

18.丢失信息的雇员

表: Employees

+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| employee_id | int     |
| name        | varchar |
+-------------+---------+
employee_id 是这个表的主键。
每一行表示雇员的id 和他的姓名。

表: Salaries

+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| employee_id | int     |
| salary      | int     |
+-------------+---------+
employee_id is 这个表的主键。
每一行表示雇员的id 和他的薪水。

写出一个查询语句,找到所有 丢失信息 的雇员id。当满足下面一个条件时,就被认为是雇员的信息丢失:

  • 雇员的 姓名 丢失了,或者
  • 雇员的 薪水信息 丢失了,或者

返回这些雇员的id  employee_id , 从小到大排序 

查询结果格式如下面的例子所示。

示例 1:

输入:
Employees table:
+-------------+----------+
| employee_id | name     |
+-------------+----------+
| 2           | Crew     |
| 4           | Haven    |
| 5           | Kristian |
+-------------+----------+
Salaries table:
+-------------+--------+
| employee_id | salary |
+-------------+--------+
| 5           | 76071  |
| 1           | 22517  |
| 4           | 63539  |
+-------------+--------+
输出:
+-------------+
| employee_id |
+-------------+
| 1           |
| 2           |
+-------------+
解释:
雇员1,2,4,5 都工作在这个公司。
1号雇员的姓名丢失了。
2号雇员的薪水信息丢失了。

SQL:

 思路:雇员的姓名丢失了或者雇员的薪水信息丢失,都会导致employee_id 在 employees 和salaries 的并集表里面仅出现一次

注意: 每个派生表都需要有自己的别名,不然执行不了。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/运维做开发/article/detail/872079
推荐阅读
相关标签
  

闽ICP备14008679号