数据库语句实践

Reference
Pandas语句
MySQL语句

一. 条件筛选

1. 大的国家

编写解决方案找出大国的国家名称、人口和面积(面积300万、人口2500万)

SELECT name, population, area FROM world WHERE area >= 3000000 OR population >= 25000000  #mysql
world[(world['area'] >= 3000000)|(world['population'] >= 25000000)][['name','population','area']] #pandas

2. 可回收且低脂的产品

编写解决方案找出既是低脂又是可回收的产品编号

SELECT product_id FROM Products WHERE low_fats = 'Y' AND recyclable = 'Y'  #mysql
world[(world['area'] >= 3000000)|(world['population'] >= 25000000)][['name','population','area']] #pandas

3. 从不订购的客户

找出所有从不点任何东西的顾客

select customers.name as 'Customers'
from customers
where customers.id not in
(
    select customerid from orders
)
mysql左连接
SELECT name AS 'Customers'
FROM Customers LEFT JOIN Orders ON Customers.Id = Orders.CustomerId
WHERE Orders.CustomerId IS NULL

4. 文章浏览

询出所有浏览过自己文章的作者

SELECT  DISTINCT author_id AS id 
FROM Views WHERE author_id = viewer_id 
ORDER BY id 

二.字符串函数

1. 无效的推文

推文长度大于15无效

SELECT  tweet_id FROM tweets WHERE  CHAR_LENGTH(content) > 15

2. 计算特殊奖学金

如果一个雇员的id 是奇数并且他的名字不是以 'M' 开头,那么他的奖金是他工资的 100% ,否则奖金为0

SELECT employee_id,
IF(employee_id % 2 = 1 AND name NOT REGEXP '^M', salary, 0) AS bonus
FROM employees 
ORDER BY employee_id

3. 恢复表中的名字

修复名字,使得只有第一个字符是大写的,其余都是小写的

SELECT user_id, CONCAT(UPPER(SUBSTRING(name, 1, 1)), LOWER(SUBSTRING(name, 2))) AS name
FROM Users
ORDER BY user_id;

4. 查找拥有有效邮箱的用户

有效的邮箱包含符合下列条件的前缀名和域名:
前缀名是包含字母(大写或小写)、数字、下划线 '_'、句点 '.' 和/或横杠 '-' 的字符串。前缀名必须以字母开头。
域名是 '@leetcode.com'

SELECT user_id, name, mail
FROM Users
WHERE mail REGEXP '^[a-zA-Z][a-zA-Z0-9_.-]*\\@leetcode\\.com$'; #必须以字母开头

5. 患某种疾病的患者

查询患有 I 类糖尿病的患者 ID (patient_id)、患者姓名(patient_name)以及其患有的所有疾病代码(conditions)

SELECT patient_id, patient_name, conditions
FROM Patients
WHERE conditions REGEXP '\\bDIAB1.*';

三. 数据操作

1. 第N高的薪水

CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
BEGIN
DECLARE M INT; 
    SET M = N-1;
  RETURN (
      SELECT DISTINCT salary
      FROM Employee
      ORDER BY salary DESC
      LIMIT M, 1
      
  );
END

2. 第二高的薪水

SELECT
    (SELECT DISTINCT Salary FROM Employee
    ORDER BY Salary DESC
    LIMIT 1 OFFSET 1) AS SecondHighestSalary

3. 部门工资最高的员工

查找出每个部门中薪资最高的员工

SELECT
    Department.name AS 'Department',
    Employee.name AS 'Employee',
    Salary
FROM
    Employee JOIN Department ON Employee.DepartmentId = Department.Id
WHERE
    (Employee.DepartmentId , Salary) IN
    (   SELECT
            DepartmentId, MAX(Salary)
        FROM
            Employee
        GROUP BY DepartmentId
    )
;

4. 分数排名

由高到底,分数相同排名相同,排名数字连续

SELECT
  S.score,
  DENSE_RANK() OVER (
    ORDER BY
      S.score DESC
  ) AS 'rank'
FROM
  Scores S;

5. 删除重复的电子邮箱

只保留一个具有最小 id 的唯一电子邮件

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

6. 每个产品在不同商店的价格

重构表,使得商店名变成属性

SELECT product_id, 'store1' AS store, store1 AS price 
FROM Products WHERE store1 IS NOT NULL

UNION 
SELECT product_id, 'store2' AS store, store2 AS price 
FROM Products WHERE store2 IS NOT NULL

UNION 
SELECT product_id, 'store3' AS store, store3 AS price 
FROM Products WHERE store3 IS NOT NULL

四. 数据统计

1. 富有客户的数量

查询至少有一个订单的金额严格大于 500 的客户的数量

SELECT COUNT(DISTINCT customer_id) AS rich_count 
FROM  Store WHERE  amount > 500

2. 即时实物配送

如果顾客期望的配送日期和下单日期相同,则该订单称为 「即时订单」,否则称为「计划订单」。
查询即时订单所占的百分比,保留两位小数。

SELECT ROUND(100 * AVG(order_date = customer_pref_delivery_date), 2) AS immediate_percentage FROM Delivery;

3. 按分类统计薪水

按薪水高低分类统计数量

SELECT  'Low Salary' AS category,
    SUM(CASE WHEN income < 20000 THEN 1 ELSE 0 END) AS accounts_count FROM  Accounts
UNION
SELECT   'Average Salary' category,
    SUM(CASE WHEN income >= 20000 AND income <= 50000 THEN 1 ELSE 0 END)  AS accounts_count FROM  Accounts
UNION
SELECT  'High Salary' category,
    SUM(CASE WHEN income > 50000 THEN 1 ELSE 0 END) AS accounts_count FROM  Accounts

五. 数据分组

1. 查询每个员工花费的总时间

计算每个员工每天花费的总时间

SELECT event_day AS day, emp_id, SUM(out_time - in_time) AS total_time
FROM Employees GROUP BY event_day, emp_id;

2. 游戏玩法分析

查询每位玩家第一次登陆平台的日期

SELECT player_id,  MIN(event_date) AS first_login
FROM Activity A GROUP BY A.player_id;

3. 每位教师所教授的科目种类的数量

查询每位老师在大学里教授的科目种类的数量

SELECT teacher_id, COUNT(DISTINCT subject_id) AS cnt
FROM Teacher GROUP BY teacher_id;

4. 超过5名学生的课

SELECT class FROM courses
GROUP BY class HAVING COUNT(student) >= 5

5. 订单最多的客户

SELECT customer_number FROM orders
GROUP BY customer_number
ORDER BY COUNT(order_number) DESC
LIMIT 1

6. 按日期分组销售产品

查询每个日期、销售的不同产品的数量及其名称。

SELECT sell_date, COUNT(DISTINCT(product)) AS num_sold, 
    GROUP_CONCAT(DISTINCT product ORDER BY product SEPARATOR ',') AS products
FROM Activities GROUP BY sell_date
ORDER BY sell_date ASC

7. 每天的领导和合伙人

对于每一个 date_id 和 make_name,返回不同的 lead_id 以及不同的 partner_id 的数量

SELECT date_id, make_name,
    COUNT(DISTINCT lead_id) AS unique_leads,
    COUNT(DISTINCT partner_id) AS unique_partners
FROM DailySales
GROUP BY date_id, make_name;

六. 数据合并

1. 查询合作过至少三次的演员和导演的 id 对

SELECT actor_id, director_id
FROM ActorDirector
GROUP BY actor_id, director_id
HAVING COUNT(*) >= 3;

2. 使用唯一标识码替换员工

SELECT  unique_id, name FROM Employees LEFT JOIN  EmployeeUNI 
ON Employees.id = EmployeeUNI.id;

3. 学生们参加各科测试的次数

SELECT 
    s.student_id, s.student_name, sub.subject_name, IFNULL(grouped.attended_exams, 0) AS attended_exams
FROM 
    Students s CROSS JOIN Subjects sub
LEFT JOIN (
    SELECT student_id, subject_name, COUNT(*) AS attended_exams
    FROM Examinations
    GROUP BY student_id, subject_name
) 
grouped  ON s.student_id = grouped.student_id AND sub.subject_name = grouped.subject_name
ORDER BY s.student_id, sub.subject_name;

4. 至少有5名直接下属的经理

SELECT name FROM employee
WHERE id IN (
    SELECT managerId FROM employee GROUP BY managerId HAVING COUNT(*) >= 5
);

5. 销售员

查询没有任何与名为 “RED” 的公司相关的订单的所有销售人员的姓名。

SELECT s.name FROM salesperson s
WHERE
    s.sales_id NOT IN (
        SELECT o.sales_id FROM orders o LEFT JOIN company c ON o.com_id = c.com_id
        WHERE c.name = 'RED')
posted @ 2023-08-02 19:28  失控D大白兔  阅读(15)  评论(0编辑  收藏  举报