SQL 练习几道题

简介: 《基础》

595. Big Countries

https://leetcode.com/problems/big-countries/description/

Description

+-----------------+------------+------------+--------------+---------------+
| name            | continent  | area       | population   | gdp           |
+-----------------+------------+------------+--------------+---------------+
| Afghanistan     | Asia       | 652230     | 25500100     | 20343000      |
| Albania         | Europe     | 28748      | 2831741      | 12960000      |
| Algeria         | Africa     | 2381741    | 37100000     | 188681000     |
| Andorra         | Europe     | 468        | 78115        | 3712000       |
| Angola          | Africa     | 1246700    | 20609294     | 100990000     |
+-----------------+------------+------------+--------------+---------------+

查找面积超过 3,000,000 或者人口数超过 25,000,000 的国家。

+--------------+-------------+--------------+
| name         | population  | area         |
+--------------+-------------+--------------+
| Afghanistan  | 25500100    | 652230       |
| Algeria      | 37100000    | 2381741      |
+--------------+-------------+--------------+

Solution

SELECT name,
    population,
    area
FROM
    World
WHERE
    area > 3000000
    OR population > 25000000;

SQL Schema

SQL Schema 用于在本地环境下创建表结构并导入数据,从而方便在本地环境调试。

DROP TABLE
IF
    EXISTS World;
CREATE TABLE World ( NAME VARCHAR ( 255 ), continent VARCHAR ( 255 ), area INT, population INT, gdp INT );
INSERT INTO World ( NAME, continent, area, population, gdp )
VALUES
    ( 'Afghanistan', 'Asia', '652230', '25500100', '203430000' ),
    ( 'Albania', 'Europe', '28748', '2831741', '129600000' ),
    ( 'Algeria', 'Africa', '2381741', '37100000', '1886810000' ),
    ( 'Andorra', 'Europe', '468', '78115', '37120000' ),
    ( 'Angola', 'Africa', '1246700', '20609294', '1009900000' );

627. Swap Salary

https://leetcode.com/problems/swap-salary/description/

Description

| id | name | sex | salary |
|----|------|-----|--------|
| 1  | A    | m   | 2500   |
| 2  | B    | f   | 1500   |
| 3  | C    | m   | 5500   |
| 4  | D    | f   | 500    |

只用一个 SQL 查询,将 sex 字段反转。

| id | name | sex | salary |
|----|------|-----|--------|
| 1  | A    | f   | 2500   |
| 2  | B    | m   | 1500   |
| 3  | C    | f   | 5500   |
| 4  | D    | m   | 500    |

Solution

两个相等的数异或的结果为 0,而 0 与任何一个数异或的结果为这个数。

sex 字段只有两个取值:'f' 和 'm',并且有以下规律:

'f' ^ ('m' ^ 'f') = 'm' ^ ('f' ^ 'f') = 'm'
'm' ^ ('m' ^ 'f') = 'f' ^ ('m' ^ 'm') = 'f'

因此将 sex 字段和 'm' ^ 'f' 进行异或操作,最后就能反转 sex 字段。

UPDATE salary
SET sex = CHAR ( ASCII(sex) ^ ASCII( 'm' ) ^ ASCII( 'f' ) );

SQL Schema

DROP TABLE
IF
    EXISTS salary;
CREATE TABLE salary ( id INT, NAME VARCHAR ( 100 ), sex CHAR ( 1 ), salary INT );
INSERT INTO salary ( id, NAME, sex, salary )
VALUES
    ( '1', 'A', 'm', '2500' ),
    ( '2', 'B', 'f', '1500' ),
    ( '3', 'C', 'm', '5500' ),
    ( '4', 'D', 'f', '500' );

620. Not Boring Movies

https://leetcode.com/problems/not-boring-movies/description/

Description

+---------+-----------+--------------+-----------+
|   id    | movie     |  description |  rating   |
+---------+-----------+--------------+-----------+
|   1     | War       |   great 3D   |   8.9     |
|   2     | Science   |   fiction    |   8.5     |
|   3     | irish     |   boring     |   6.2     |
|   4     | Ice song  |   Fantacy    |   8.6     |
|   5     | House card|   Interesting|   9.1     |
+---------+-----------+--------------+-----------+

查找 id 为奇数,并且 description 不是 boring 的电影,按 rating 降序。

+---------+-----------+--------------+-----------+
|   id    | movie     |  description |  rating   |
+---------+-----------+--------------+-----------+
|   5     | House card|   Interesting|   9.1     |
|   1     | War       |   great 3D   |   8.9     |
+---------+-----------+--------------+-----------+

Solution

SELECT
    *
FROM
    cinema
WHERE
    id % 2 = 1
    AND description != 'boring'
ORDER BY
    rating DESC;

SQL Schema

DROP TABLE
IF
    EXISTS cinema;
CREATE TABLE cinema ( id INT, movie VARCHAR ( 255 ), description VARCHAR ( 255 ), rating FLOAT ( 2, 1 ) );
INSERT INTO cinema ( id, movie, description, rating )
VALUES
    ( 1, 'War', 'great 3D', 8.9 ),
    ( 2, 'Science', 'fiction', 8.5 ),
    ( 3, 'irish', 'boring', 6.2 ),
    ( 4, 'Ice song', 'Fantacy', 8.6 ),
    ( 5, 'House card', 'Interesting', 9.1 );

596. Classes More Than 5 Students

https://leetcode.com/problems/classes-more-than-5-students/description/

Description

+---------+------------+
| student | class      |
+---------+------------+
| A       | Math       |
| B       | English    |
| C       | Math       |
| D       | Biology    |
| E       | Math       |
| F       | Computer   |
| G       | Math       |
| H       | Math       |
| I       | Math       |
+---------+------------+

查找有五名及以上 student 的 class。

+---------+
| class   |
+---------+
| Math    |
+---------+

Solution

对 class 列进行分组之后,再使用 count 汇总函数统计每个分组的记录个数,之后使用 HAVING 进行筛选。HAVING 针对分组进行筛选,而 WHERE 针对每个记录(行)进行筛选。

SELECT
    class
FROM
    courses
GROUP BY
    class
HAVING
    count( DISTINCT student ) >= 5;

SQL Schema

DROP TABLE
IF
    EXISTS courses;
CREATE TABLE courses ( student VARCHAR ( 255 ), class VARCHAR ( 255 ) );
INSERT INTO courses ( student, class )
VALUES
    ( 'A', 'Math' ),
    ( 'B', 'English' ),
    ( 'C', 'Math' ),
    ( 'D', 'Biology' ),
    ( 'E', 'Math' ),
    ( 'F', 'Computer' ),
    ( 'G', 'Math' ),
    ( 'H', 'Math' ),
    ( 'I', 'Math' );

182. Duplicate Emails

https://leetcode.com/problems/duplicate-emails/description/

Description

邮件地址表:

+----+---------+
| Id | Email   |
+----+---------+
| 1  | a@b.com |
| 2  | c@d.com |
| 3  | a@b.com |
+----+---------+

查找重复的邮件地址:

+---------+
| Email   |
+---------+
| a@b.com |
+---------+

Solution

对 Email 进行分组,如果并使用 COUNT 进行计数统计,结果大于等于 2 的表示 Email 重复。

SELECT
    Email
FROM
    Person
GROUP BY
    Email
HAVING
    COUNT( * ) >= 2;

SQL Schema

DROP TABLE
IF
    EXISTS Person;
CREATE TABLE Person ( Id INT, Email VARCHAR ( 255 ) );
INSERT INTO Person ( Id, Email )
VALUES
    ( 1, 'a@b.com' ),
    ( 2, 'c@d.com' ),
    ( 3, 'a@b.com' );

196. Delete Duplicate Emails

https://leetcode.com/problems/delete-duplicate-emails/description/

Description

邮件地址表:

+----+---------+
| Id | Email   |
+----+---------+
| 1  | john@example.com |
| 2  | bob@example.com |
| 3  | john@example.com |
+----+---------+

删除重复的邮件地址:

+----+------------------+
| Id | Email            |
+----+------------------+
| 1  | john@example.com |
| 2  | bob@example.com  |
+----+------------------+

Solution

只保留相同 Email 中 Id 最小的那一个,然后删除其它的。

连接查询:

DELETE p1
FROM
    Person p1,
    Person p2
WHERE
    p1.Email = p2.Email
    AND p1.Id > p2.Id

子查询:

DELETE
FROM
    Person
WHERE
    id NOT IN (
        SELECT id 
        FROM ( 
            SELECT min( id ) AS id 
            FROM Person
            GROUP BY email
        ) AS m
    );

应该注意的是上述解法额外嵌套了一个 SELECT 语句,如果不这么做,会出现错误:You can't specify target table 'Person' for update in FROM clause。以下演示了这种错误解法。

DELETE
FROM
    Person
WHERE
    id NOT IN ( 
        SELECT min( id ) AS id 
        FROM Person 
        GROUP BY email 
    );

参考:pMySQL Error 1093 - Can't specify target table for update in FROM clause(opens new window)

SQL Schema

与 182 相同。

相关文章
|
2月前
|
SQL Perl
PL/SQL经典练习
PL/SQL经典练习
14 0
|
5月前
|
SQL 分布式计算 数据挖掘
Hive SQL初级练习(30题)
Hive SQL初级练习(30题)
|
7月前
|
SQL 存储 Java
Mybatis实战练习四【单个条件(动态SQL)&添加数据】(下)
Mybatis实战练习四【单个条件(动态SQL)&添加数据】
|
7月前
|
SQL 存储 关系型数据库
【MYSQL高级】Mysql 表的七种连接方式【附带练习sql】
【MYSQL高级】Mysql 表的七种连接方式【附带练习sql】
98 0
|
7月前
|
SQL Java 数据库连接
Mybatis实战练习四【单个条件(动态SQL)&添加数据】(上)
Mybatis实战练习四【单个条件(动态SQL)&添加数据】
|
4月前
|
SQL
SQL语句多表查询练习
SQL语句多表查询练习
12 0
|
4月前
|
SQL 关系型数据库 MySQL
mysql查询语句练习总结(涵盖所有sql语法)
mysql查询语句练习总结(涵盖所有sql语法)
|
6月前
|
SQL 算法 JavaScript
在线就能用的 SQL 练习平台(附SQL学习文档)
在线就能用的 SQL 练习平台(附SQL学习文档)
174 0
|
10月前
|
SQL 数据挖掘 数据库
牛客网之SQL刷题练习——一个实用的网站
牛客网之SQL刷题练习——一个实用的网站
265 0
|
11月前
|
SQL 数据库
学通4中数据库SQL教程练习和答案
编写一个SQL语句,输出下面的结果