來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problemset/database/
文章目錄
- SQL結構:
- 579. 查詢員工的累計薪水(困難)
- 解法一
- SQL結構:
- 601. 體育館的人流量(困難)
- 解法一
SQL結構:
Create table If Not Exists Employee (Id int, Month int, Salary int)
Truncate table Employee
insert into Employee (Id, Month, Salary) values ('1', '1', '20')
insert into Employee (Id, Month, Salary) values ('2', '1', '20')
insert into Employee (Id, Month, Salary) values ('1', '2', '30')
insert into Employee (Id, Month, Salary) values ('2', '2', '30')
insert into Employee (Id, Month, Salary) values ('3', '2', '40')
insert into Employee (Id, Month, Salary) values ('1', '3', '40')
insert into Employee (Id, Month, Salary) values ('3', '3', '60')
insert into Employee (Id, Month, Salary) values ('1', '4', '60')
insert into Employee (Id, Month, Salary) values ('3', '4', '70')
579. 查詢員工的累計薪水(困難)
Employee 表保存了一年內的薪水資訊,
需求:請你撰寫 SQL 陳述句,對于每個員工,查詢他除最近一個月(即最大月)之外,剩下每個月的近三個月的累計薪水(不足三個月也要計算),
結果請按 Id 升序,然后按 Month 降序顯示,
示例:
輸入:
| Id | Month | Salary |
|----|-------|--------|
| 1 | 1 | 20 |
| 2 | 1 | 20 |
| 1 | 2 | 30 |
| 2 | 2 | 30 |
| 3 | 2 | 40 |
| 1 | 3 | 40 |
| 3 | 3 | 60 |
| 1 | 4 | 60 |
| 3 | 4 | 70 |
輸出:
| Id | Month | Salary |
|----|-------|--------|
| 1 | 3 | 90 |
| 1 | 2 | 50 |
| 1 | 1 | 20 |
| 2 | 1 | 20 |
| 3 | 3 | 100 |
| 3 | 2 | 40 |
解釋:
員工 ‘1’ 除去最近一個月(月份 ‘4’),有三個月的薪水記錄:月份 ‘3’ 薪水為 40,月份 ‘2’ 薪水為 30,月份 ‘1’ 薪水為 20,
所以近 3 個月的薪水累計分別為 (40 + 30 + 20) = 90,(30 + 20) = 50 和 20,
| Id | Month | Salary |
|----|-------|--------|
| 1 | 3 | 90 |
| 1 | 2 | 50 |
| 1 | 1 | 20 |
員工 ‘2’ 除去最近的一個月(月份 ‘2’)的話,只有月份 ‘1’ 這一個月的薪水記錄,
| Id | Month | Salary |
|----|-------|--------|
| 2 | 1 | 20 |
員工 ‘3’ 除去最近一個月(月份 ‘4’)后有兩個月,分別為:月份 ‘4’ 薪水為 60 和 月份 ‘2’ 薪水為 40,所以各月的累計情況如下:
| Id | Month | Salary |
|----|-------|--------|
| 3 | 3 | 100 |
| 3 | 2 | 40 |
解法一
-- 先用開窗lead(),取后一個月份,取不到補0,為了過濾最大月份,即值為0的為最大月份
-- 再用開窗sum(),直接求近三個月的和,所以需要用到rows between來確定范圍,即(上兩條 到 當前行)
-- 最后用id、月份desc排序
SELECT
Id,
Month,
SUM(Salary) OVER (PARTITION BY Id ORDER BY Month ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) Salary
FROM
(
SELECT
Id,
Month,
Salary,
LEAD(Month, 1, 0) OVER (PARTITION BY Id ORDER BY Month) lm
FROM
Employee
) t1
WHERE
lm != 0
ORDER BY
Id, Month DESC
----------------------------華麗的分割線--------------------------------
SQL結構:
Create table If Not Exists stadium (id int, visit_date DATE NULL, people int);
Truncate table stadium;
insert into stadium (id, visit_date, people) values ('1', '2017-01-01', '10');
insert into stadium (id, visit_date, people) values ('2', '2017-01-02', '109');
insert into stadium (id, visit_date, people) values ('3', '2017-01-03', '150');
insert into stadium (id, visit_date, people) values ('4', '2017-01-04', '99');
insert into stadium (id, visit_date, people) values ('5', '2017-01-05', '145');
insert into stadium (id, visit_date, people) values ('6', '2017-01-06', '1455');
insert into stadium (id, visit_date, people) values ('7', '2017-01-07', '199');
insert into stadium (id, visit_date, people) values ('8', '2017-01-08', '188');
601. 體育館的人流量(困難)
X 市建了一個新的體育館,每日人流量資訊被記錄在這三列資訊中:序號 (id)、日期 (visit_date)、 人流量 (people),
需求:請撰寫一個查詢陳述句,找出人流量的高峰期,高峰期時,至少連續三行記錄中的人流量不少于100,
例如,表 stadium:
+------+------------+-----------+
| id | visit_date | people |
+------+------------+-----------+
| 1 | 2017-01-01 | 10 |
| 2 | 2017-01-02 | 109 |
| 3 | 2017-01-03 | 150 |
| 4 | 2017-01-04 | 99 |
| 5 | 2017-01-05 | 145 |
| 6 | 2017-01-06 | 1455 |
| 7 | 2017-01-07 | 199 |
| 8 | 2017-01-08 | 188 |
+------+------------+-----------+
對于上面的示例資料,輸出為:
+------+------------+-----------+
| id | visit_date | people |
+------+------------+-----------+
| 5 | 2017-01-05 | 145 |
| 6 | 2017-01-06 | 1455 |
| 7 | 2017-01-07 | 199 |
| 8 | 2017-01-08 | 188 |
+------+------------+-----------+
提示:
- 每天只有一行記錄,日期隨著 id 的增加而增加,
- 體育館并不是每天都開放的,所以記錄中的日期可能會出現斷層,
解法一
思路:連續N天,只要是連續的,都可以用等差的思想;
即(用某個連續欄位 - 行號/排行 ),若是連續的,差值一定相同,再統計相同差值的個數即可,
-- 先過濾出人流程量>=100的記錄,然后再用id - 行號,得出差值(因為id是連續的)
-- 再統計出,差值相同的個數,即個數多少,就連續多少,
-- 最后根據條件 where 連續個數>=3 的記錄即可,
SELECT
id,
visit_date,
people
FROM
(
SELECT
id,
visit_date,
people,
COUNT(*) OVER (PARTITION BY diff_value) AS diff_value_number
FROM
(
SELECT
id,
visit_date,
people,
id - (ROW_NUMBER() OVER (ORDER BY id)) AS diff_value
FROM
stadium
WHERE
people >= 100
) AS t1
) AS t2
WHERE
t2.diff_value_number >= 3
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/62962.html
標籤:其他
