SQL練習(xí)題七

71.即時(shí)事物配送2

寫一條 SQL 查詢語(yǔ)句獲取即時(shí)訂單在所有用戶的首次訂單中的比例。保留兩位小數(shù)。

配送表: Delivery

+-----------------------------+---------+
| Column Name                 | Type    |
+-----------------------------+---------+
| delivery_id                 | int     |
| customer_id                 | int     |
| order_date                  | date    |
| customer_pref_delivery_date | date    |
+-----------------------------+---------+
delivery_id 是表的主鍵。
該表保存著顧客的食物配送信息,顧客在某個(gè)日期下了訂單,并指定了一個(gè)期望的配送日期(和下單日期相同或者在那之后)。
 

如果顧客期望的配送日期和下單日期相同,則該訂單稱為 「即時(shí)訂單」,否則稱為「計(jì)劃訂單」。

「首次訂單」是顧客最早創(chuàng)建的訂單。我們保證一個(gè)顧客只會(huì)有一個(gè)「首次訂單」。

寫一條 SQL 查詢語(yǔ)句獲取即時(shí)訂單在所有用戶的首次訂單中的比例。保留兩位小數(shù)。

 

查詢結(jié)果如下所示:

Delivery 表:
+-------------+-------------+------------+-----------------------------+
| delivery_id | customer_id | order_date | customer_pref_delivery_date |
+-------------+-------------+------------+-----------------------------+
| 1           | 1           | 2019-08-01 | 2019-08-02                  |
| 2           | 2           | 2019-08-02 | 2019-08-02                  |
| 3           | 1           | 2019-08-11 | 2019-08-12                  |
| 4           | 3           | 2019-08-24 | 2019-08-24                  |
| 5           | 3           | 2019-08-21 | 2019-08-22                  |
| 6           | 2           | 2019-08-11 | 2019-08-13                  |
| 7           | 4           | 2019-08-09 | 2019-08-09                  |
+-------------+-------------+------------+-----------------------------+

Result 表:
+----------------------+
| immediate_percentage |
+----------------------+
| 50.00                |
+----------------------+
1 號(hào)顧客的 1 號(hào)訂單是首次訂單,并且是計(jì)劃訂單。
2 號(hào)顧客的 2 號(hào)訂單是首次訂單,并且是即時(shí)訂單。
3 號(hào)顧客的 5 號(hào)訂單是首次訂單,并且是計(jì)劃訂單。
4 號(hào)顧客的 7 號(hào)訂單是首次訂單,并且是即時(shí)訂單。
因此,一半顧客的首次訂單是即時(shí)的
--我的寫法,考慮可能有的用戶沒有首次購(gòu)買時(shí)間?,可以優(yōu)化一下,把獲取總的首次購(gòu)買的總數(shù)直接count(1) 而不是用子查詢獲取

select 
round((count(1) / (select count(distinct customer_id) from Delivery)) *100,2) as immediate_percentage
from 
Delivery
where order_date = customer_pref_delivery_date
and (customer_id,order_date) in 
(
select
customer_id,min(order_date) as da
from
Delivery
group by customer_id
)
select round(sum(order_date=customer_pref_delivery_date)/count(*)*100,2) immediate_percentage
from(
    select order_date,customer_pref_delivery_date,
           rank() over (partition by customer_id order by order_date) r
    from Delivery
) a
where r=1

72.重新格式化部門表

編寫一個(gè) SQL 查詢來重新格式化表,使得新的表中有一個(gè)部門 id 列和一些對(duì)應(yīng) 每個(gè)月 的收入(revenue)列。

部門表 Department:

+---------------+---------+
| Column Name   | Type    |
+---------------+---------+
| id            | int     |
| revenue       | int     |
| month         | varchar |
+---------------+---------+
(id, month) 是表的聯(lián)合主鍵。
這個(gè)表格有關(guān)于每個(gè)部門每月收入的信息。
月份(month)可以取下列值 ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]。
 

編寫一個(gè) SQL 查詢來重新格式化表,使得新的表中有一個(gè)部門 id 列和一些對(duì)應(yīng) 每個(gè)月 的收入(revenue)列。

查詢結(jié)果格式如下面的示例所示:

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

查詢得到的結(jié)果表:
+------+-------------+-------------+-------------+-----+-------------+
| id   | Jan_Revenue | Feb_Revenue | Mar_Revenue | ... | Dec_Revenue |
+------+-------------+-------------+-------------+-----+-------------+
| 1    | 8000        | 7000        | 6000        | ... | null        |
| 2    | 9000        | null        | null        | ... | null        |
| 3    | null        | 10000       | null        | ... | null        |
+------+-------------+-------------+-------------+-----+-------------+

注意,結(jié)果表有 13 列 (1個(gè)部門 id 列 + 12個(gè)月份的收入列)。
-- 簡(jiǎn)單題,考察group by 和聚合函數(shù)
select
id,
sum(if(month = "Jan",revenue,null)) as Jan_Revenue,
sum(if(month = "Feb",revenue,null)) as Feb_Revenue,
sum(if(month = "Mar",revenue,null)) as Mar_Revenue,
sum(if(month = "Apr",revenue,null)) as Apr_Revenue,
sum(if(month = "May",revenue,null)) as May_Revenue,
sum(if(month = "Jun",revenue,null)) as Jun_Revenue,
sum(if(month = "Jul",revenue,null)) as Jul_Revenue,
sum(if(month = "Aug",revenue,null)) as Aug_Revenue,
sum(if(month = "Sep",revenue,null)) as Sep_Revenue,
sum(if(month = "Oct",revenue,null)) as Oct_Revenue,
sum(if(month = "Nov",revenue,null)) as Nov_Revenue,
sum(if(month = "Dec",revenue,null)) as Dec_Revenue
from
Department
group by id
select 
     id
    , sum(case `month` when 'Jan' then revenue else null end) as Jan_Revenue
    , sum(case `month` when 'Feb' then revenue else null end) as Feb_Revenue
    , sum(case `month` when 'Mar' then revenue else null end) as Mar_Revenue
    , sum(case `month` when 'Apr' then revenue else null end) as Apr_Revenue
    , sum(case `month` when 'May' then revenue else null end) as May_Revenue
    , sum(case `month` when 'Jun' then revenue else null end) as Jun_Revenue
    , sum(case `month` when 'Jul' then revenue else null end) as Jul_Revenue
    , sum(case `month` when 'Aug' then revenue else null end) as Aug_Revenue
    , sum(case `month` when 'Sep' then revenue else null end) as Sep_Revenue
    , sum(case `month` when 'Oct' then revenue else null end) as Oct_Revenue
    , sum(case `month` when 'Nov' then revenue else null end) as Nov_Revenue
    , sum(case `month` when 'Dec' then revenue else null end) as Dec_Revenue
from Department group by id

73.每月交易1

編寫一個(gè) sql 查詢來查找每個(gè)月和每個(gè)國(guó)家/地區(qū)的事務(wù)數(shù)及其總金額、已批準(zhǔn)的事務(wù)數(shù)及其總金額。

Table: Transactions

+---------------+---------+
| Column Name   | Type    |
+---------------+---------+
| id            | int     |
| country       | varchar |
| state         | enum    |
| amount        | int     |
| trans_date    | date    |
+---------------+---------+
id 是這個(gè)表的主鍵。
該表包含有關(guān)傳入事務(wù)的信息。
state 列類型為 “[”批準(zhǔn)“,”拒絕“] 之一。
 

編寫一個(gè) sql 查詢來查找每個(gè)月和每個(gè)國(guó)家/地區(qū)的事務(wù)數(shù)及其總金額、已批準(zhǔn)的事務(wù)數(shù)及其總金額。

查詢結(jié)果格式如下所示:

Transactions table:
+------+---------+----------+--------+------------+
| id   | country | state    | amount | trans_date |
+------+---------+----------+--------+------------+
| 121  | US      | approved | 1000   | 2018-12-18 |
| 122  | US      | declined | 2000   | 2018-12-19 |
| 123  | US      | approved | 2000   | 2019-01-01 |
| 124  | DE      | approved | 2000   | 2019-01-07 |
+------+---------+----------+--------+------------+

Result table:
+----------+---------+-------------+----------------+--------------------+-----------------------+
| month    | country | trans_count | approved_count | trans_total_amount | approved_total_amount |
+----------+---------+-------------+----------------+--------------------+-----------------------+
| 2018-12  | US      | 2           | 1              | 3000               | 1000                  |
| 2019-01  | US      | 1           | 1              | 2000               | 2000                  |
| 2019-01  | DE      | 1           | 1              | 2000               | 2000                  |
+----------+---------+-------------+----------------+--------------------+-----------------------+
-- 簡(jiǎn)單題,可以使用date_format或者left函數(shù)
select
substr(trans_date,1,7) month , country,count(state) trans_count,
sum(state = "approved") approved_count ,sum(amount) trans_total_amount,
sum(if(state = "approved",amount,0)) approved_total_amount
from
Transactions
group by country,substr(trans_date,1,7)
select date_format(trans_date,"%Y-%m") month
,country,count(id) trans_count
,count(if(state<>"approved",null,state)) approved_count
,sum(amount) trans_total_amount
,sum(amount*(state<>"declined"))  approved_total_amount
from transactions 
group by date_format(trans_date,"%Y-%m"),country;

注意在group by之后使用count(字段=?) 統(tǒng)計(jì)的是全部的行,如果要過濾要使用case when 或者 if 來過濾例如:

count(if(state<>"approved",null,state)) approved_count

74.錦標(biāo)賽優(yōu)勝者

編寫一個(gè) SQL 查詢來查找每組中的獲勝者。

Players 玩家表

+-------------+-------+
| Column Name | Type  |
+-------------+-------+
| player_id   | int   |
| group_id    | int   |
+-------------+-------+
player_id 是此表的主鍵。
此表的每一行表示每個(gè)玩家的組。
Matches 賽事表

+---------------+---------+
| Column Name   | Type    |
+---------------+---------+
| match_id      | int     |
| first_player  | int     |
| second_player | int     | 
| first_score   | int     |
| second_score  | int     |
+---------------+---------+
match_id 是此表的主鍵。
每一行是一場(chǎng)比賽的記錄,first_player 和 second_player 表示該場(chǎng)比賽的球員 ID。
first_score 和 second_score 分別表示 first_player 和 second_player 的得分。
你可以假設(shè),在每一場(chǎng)比賽中,球員都屬于同一組。
 

每組的獲勝者是在組內(nèi)累積得分最高的選手。如果平局,player_id 最小 的選手獲勝。

編寫一個(gè) SQL 查詢來查找每組中的獲勝者。

查詢結(jié)果格式如下所示

Players 表:
+-----------+------------+
| player_id | group_id   |
+-----------+------------+
| 15        | 1          |
| 25        | 1          |
| 30        | 1          |
| 45        | 1          |
| 10        | 2          |
| 35        | 2          |
| 50        | 2          |
| 20        | 3          |
| 40        | 3          |
+-----------+------------+

Matches 表:
+------------+--------------+---------------+-------------+--------------+
| match_id   | first_player | second_player | first_score | second_score |
+------------+--------------+---------------+-------------+--------------+
| 1          | 15           | 45            | 3           | 0            |
| 2          | 30           | 25            | 1           | 2            |
| 3          | 30           | 15            | 2           | 0            |
| 4          | 40           | 20            | 5           | 2            |
| 5          | 35           | 50            | 1           | 1            |
+------------+--------------+---------------+-------------+--------------+

Result 表:
+-----------+------------+
| group_id  | player_id  |
+-----------+------------+ 
| 1         | 15         |
| 2         | 35         |
| 3         | 40         |
+-----------+------------+
--我的寫法先獲取每個(gè)人的分?jǐn)?shù),然后在組內(nèi)比較獲取最大值
select
group_id,player_id 
from 
(
select
group_id,player_id,row_number() over( partition by group_id order by score desc ,player_id asc ) as rn 
from 
Players
join 
(
select 
player,sum(score) as score
from 
(
select
first_player as player ,sum(first_score) as score
from
Matches
group by first_player
union all 
select 
second_player ,sum(second_score)
from
Matches
group by second_player
)
group by player
) t2
on Players.player_id = t2.player
) 
where rn =1
-- 使用first_value可以減少嵌套一層select 
SELECT DISTINCT group_id,  
       FIRST_VALUE(player_id) OVER(PARTITION BY group_id ORDER BY score DESC, player_id) AS player_id
FROM
    (SELECT p.group_id,
            p.player_id,
            SUM(score)AS score
    FROM
        (SELECT first_player AS player_id, first_score AS score
        FROM Matches
        UNION ALL
        SELECT second_player AS player_id, second_score AS score
        FROM Matches) t1
    LEFT JOIN 
        Players p 
    ON t1.player_id = p.player_id
    GROUP BY player_id) t2
-- 偷懶寫法,group by 默認(rèn)返回第一行
select group_id, player_id
from (
    select players.*, sum(if(player_id = first_player, first_score, second_score)) score
    from players join matches
    on player_id = first_player or player_id = second_player
    group by player_id
    order by score desc, player_id
) tmp
group by group_id

75.最后一個(gè)能進(jìn)入電梯的人(自連接)

寫一條 SQL 查詢語(yǔ)句查找最后一個(gè)能進(jìn)入電梯且不超過重量限制的 person_name 。題目確保隊(duì)列中第一位的人可以進(jìn)入電梯 。

表: Queue

+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| person_id   | int     |
| person_name | varchar |
| weight      | int     |
| turn        | int     |
+-------------+---------+
person_id 是這個(gè)表的主鍵。
該表展示了所有等待電梯的人的信息。
表中 person_id 和 turn 列將包含從 1 到 n 的所有數(shù)字,其中 n 是表中的行數(shù)。
 

電梯最大載重量為 1000。

寫一條 SQL 查詢語(yǔ)句查找最后一個(gè)能進(jìn)入電梯且不超過重量限制的 person_name 。題目確保隊(duì)列中第一位的人可以進(jìn)入電梯 。

查詢結(jié)果如下所示 :

Queue 表
+-----------+-------------------+--------+------+
| person_id | person_name       | weight | turn |
+-----------+-------------------+--------+------+
| 5         | George Washington | 250    | 1    |
| 3         | John Adams        | 350    | 2    |
| 6         | Thomas Jefferson  | 400    | 3    |
| 2         | Will Johnliams    | 200    | 4    |
| 4         | Thomas Jefferson  | 175    | 5    |
| 1         | James Elephant    | 500    | 6    |
+-----------+-------------------+--------+------+

Result 表
+-------------------+
| person_name       |
+-------------------+
| Thomas Jefferson  |
+-------------------+

為了簡(jiǎn)化,Queue 表按 turn 列由小到大排序。
上例中 George Washington(id 5), John Adams(id 3) 和 Thomas Jefferson(id 6) 將可以進(jìn)入電梯,因?yàn)樗麄兊捏w重和為 250 + 350 + 400 = 1000。
Thomas Jefferson(id 6) 是最后一個(gè)體重合適并進(jìn)入電梯的人。
--我的寫法,窗口寫法
select 
person_name
from 
(
select
person_name,rank() over(order by weight_rn desc )  as rn 
from 
(
select
person_name,
sum(weight) over(order by turn ) as weight_rn  
from
Queue
) 
where weight_rn <= 1000
) 
where rn =1
--自連接,where t1.turn >= t2.turn計(jì)算直到當(dāng)前的總的質(zhì)量
select t1.person_name
from queue t1, queue t2
where t1.turn >= t2.turn
group by t1.turn 
having sum(t2.weight) <= 1000
order by t1.turn desc
limit 1

76.每月交易2(tag)☆

編寫一個(gè) SQL 查詢,以查找每個(gè)月和每個(gè)國(guó)家/地區(qū)的已批準(zhǔn)交易的數(shù)量及其總金額、退單的數(shù)量及其總金額。
注意:在您的查詢中,給定月份和國(guó)家,忽略所有為零的行。

Transactions 記錄表

+----------------+---------+
| Column Name    | Type    |
+----------------+---------+
| id             | int     |
| country        | varchar |
| state          | enum    |
| amount         | int     |
| trans_date     | date    |
+----------------+---------+
id 是這個(gè)表的主鍵。
該表包含有關(guān)傳入事務(wù)的信息。
狀態(tài)列是類型為 [approved(已批準(zhǔn))、declined(已拒絕)] 的枚舉。
 

Chargebacks 表

+----------------+---------+
| Column Name    | Type    |
+----------------+---------+
| trans_id       | int     |
| charge_date    | date    |
+----------------+---------+
退單包含有關(guān)放置在事務(wù)表中的某些事務(wù)的傳入退單的基本信息。
trans_id 是 transactions 表的 id 列的外鍵。
每項(xiàng)退單都對(duì)應(yīng)于之前進(jìn)行的交易,即使未經(jīng)批準(zhǔn)。
 

編寫一個(gè) SQL 查詢,以查找每個(gè)月和每個(gè)國(guó)家/地區(qū)的已批準(zhǔn)交易的數(shù)量及其總金額、退單的數(shù)量及其總金額。

注意:在您的查詢中,給定月份和國(guó)家,忽略所有為零的行。

查詢結(jié)果格式如下所示:

Transactions 表:
+------+---------+----------+--------+------------+
| id   | country | state    | amount | trans_date |
+------+---------+----------+--------+------------+
| 101  | US      | approved | 1000   | 2019-05-18 |
| 102  | US      | declined | 2000   | 2019-05-19 |
| 103  | US      | approved | 3000   | 2019-06-10 |
| 104  | US      | declined | 4000   | 2019-06-13 |
| 105  | US      | approved | 5000   | 2019-06-15 |
+------+---------+----------+--------+------------+

Chargebacks 表:
+------------+------------+
| trans_id   | trans_date |
+------------+------------+
| 102        | 2019-05-29 |
| 101        | 2019-06-30 |
| 105        | 2019-09-18 |
+------------+------------+

Result 表:
+----------+---------+----------------+-----------------+-------------------+--------------------+
| month    | country | approved_count | approved_amount | chargeback_count  | chargeback_amount  |
+----------+---------+----------------+-----------------+-------------------+--------------------+
| 2019-05  | US      | 1              | 1000            | 1                 | 2000               |
| 2019-06  | US      | 2              | 8000            | 1                 | 1000               |
| 2019-09  | US      | 0              | 0               | 1                 | 5000               |
+----------+---------+----------------+-----------------+-------------------+------------------
-- 總少了一個(gè)國(guó)家,我裂開了.....沒有full join難受
select 
t1.dt as month ,t1.country,approved_count,approved_amount,chargeback_count,chargeback_amount
from 
(
select
country,left(trans_date,7) as dt ,ifnull(sum(state ="approved"),0) as approved_count,
ifnull(sum(if(state ="approved",amount,0)),0) as approved_amount
from
Transactions
group by country, left(trans_date,7)
) t1 
left   join 
(
select
country,left(Chargebacks.trans_date,7) as dt ,ifnull(count(1),0) as chargeback_count ,ifnull(sum(amount),0) as chargeback_amount
from 
Transactions
join Chargebacks on Transactions.id = Chargebacks.trans_id and left(Chargebacks.trans_date,7) = left( Transactions.trans_date,7)
group by country,left(Chargebacks.trans_date,7)
) t2
on t1.country = t2.country and t1.dt = t2.dt
--學(xué)習(xí)使用tag用法,妙!!!!
select
    date_format(trans_date, '%Y-%m') as month,
    country,
    sum(if(state = 'approved',1,0)) as approved_count,
    sum(if(state = 'approved',amount,0)) as approved_amount,
    sum(if(state = 'chargeback',1,0)) as chargeback_count,
    sum(if(state = 'chargeback',amount,0)) as chargeback_amount
from
    (select
        *
    from
        transactions
    union all
    select
        trans_id as id,
        country,
        'chargeback' as state,
        amount,
        c.trans_date
    from
        chargebacks c left join transactions t 
        on t.id = c.trans_id) as temp
group by 1,2
having approved_count <> 0 or chargeback_count <> 0

防止為0

having approved_count <> 0 or chargeback_count <> 0

77.查詢結(jié)果的質(zhì)量與占比

編寫一組 SQL 來查找每次查詢的名稱(query_name)、質(zhì)量(quality) 和 劣質(zhì)查詢百分比(poor_query_percentage)。
質(zhì)量(quality) 和劣質(zhì)查詢百分比(poor_query_percentage) 都應(yīng)四舍五入到小數(shù)點(diǎn)后兩位。

查詢表 Queries: 

+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| query_name  | varchar |
| result      | varchar |
| position    | int     |
| rating      | int     |
+-------------+---------+
此表沒有主鍵,并可能有重復(fù)的行。
此表包含了一些從數(shù)據(jù)庫(kù)中收集的查詢信息。
“位置”(position)列的值為 1 到 500 。
“評(píng)分”(rating)列的值為 1 到 5 。評(píng)分小于 3 的查詢被定義為質(zhì)量很差的查詢。
 

將查詢結(jié)果的質(zhì)量 quality 定義為:

各查詢結(jié)果的評(píng)分與其位置之間比率的平均值。

將劣質(zhì)查詢百分比 poor_query_percentage 為:

評(píng)分小于 3 的查詢結(jié)果占全部查詢結(jié)果的百分比。

編寫一組 SQL 來查找每次查詢的名稱(query_name)、質(zhì)量(quality) 和 劣質(zhì)查詢百分比(poor_query_percentage)。

質(zhì)量(quality) 和劣質(zhì)查詢百分比(poor_query_percentage) 都應(yīng)四舍五入到小數(shù)點(diǎn)后兩位。

查詢結(jié)果格式如下所示:

Queries table:
+------------+-------------------+----------+--------+
| query_name | result            | position | rating |
+------------+-------------------+----------+--------+
| Dog        | Golden Retriever  | 1        | 5      |
| Dog        | German Shepherd   | 2        | 5      |
| Dog        | Mule              | 200      | 1      |
| Cat        | Shirazi           | 5        | 2      |
| Cat        | Siamese           | 3        | 3      |
| Cat        | Sphynx            | 7        | 4      |
+------------+-------------------+----------+--------+

Result table:
+------------+---------+-----------------------+
| query_name | quality | poor_query_percentage |
+------------+---------+-----------------------+
| Dog        | 2.50    | 33.33                 |
| Cat        | 0.66    | 33.33                 |
+------------+---------+-----------------------+

Dog 查詢結(jié)果的質(zhì)量為 ((5 / 1) + (5 / 2) + (1 / 200)) / 3 = 2.50
Dog 查詢結(jié)果的劣質(zhì)查詢百分比為 (1 / 3) * 100 = 33.33

Cat 查詢結(jié)果的質(zhì)量為 ((2 / 5) + (3 / 3) + (4 / 7)) / 3 = 0.66
Cat 查詢結(jié)果的劣質(zhì)查詢百分比為 (1 / 3) * 100 = 33.33
--讀懂題意,簡(jiǎn)單題
select 
query_name,round(sum(rating/position) /count(1),2) as quality,
round(sum(rating < 3) /count(1) *100 ,2)as poor_query_percentage
from
Queries
group by query_name
SELECT 
    query_name, 
    ROUND(AVG(rating/position), 2) quality,
    ROUND(avg(rating < 3) * 100,2) poor_query_percentage
FROM Queries
GROUP BY query_name

78.查詢球隊(duì)積分

寫出一條SQL語(yǔ)句以查詢每個(gè)隊(duì)的 team_id,team_name 和 num_points。結(jié)果根據(jù) num_points 降序排序,如果有兩隊(duì)積分相同,那么這兩隊(duì)按 team_id 升序排序

Table: Teams

+---------------+----------+
| Column Name   | Type     |
+---------------+----------+
| team_id       | int      |
| team_name     | varchar  |
+---------------+----------+
此表的主鍵是 team_id,表中的每一行都代表一支獨(dú)立足球隊(duì)。
Table: Matches

+---------------+---------+
| Column Name   | Type    |
+---------------+---------+
| match_id      | int     |
| host_team     | int     |
| guest_team    | int     | 
| host_goals    | int     |
| guest_goals   | int     |
+---------------+---------+
此表的主鍵是 match_id,表中的每一行都代表一場(chǎng)已結(jié)束的比賽,比賽的主客隊(duì)分別由它們自己的 id 表示,他們的進(jìn)球由 host_goals 和 guest_goals 分別表示。
 

積分規(guī)則如下:

贏一場(chǎng)得三分;
平一場(chǎng)得一分;
輸一場(chǎng)不得分。
寫出一條SQL語(yǔ)句以查詢每個(gè)隊(duì)的 team_id,team_name 和 num_points。結(jié)果根據(jù) num_points 降序排序,如果有兩隊(duì)積分相同,那么這兩隊(duì)按 team_id  升序排序。

查詢結(jié)果格式如下:

Teams table:
+-----------+--------------+
| team_id   | team_name    |
+-----------+--------------+
| 10        | Leetcode FC  |
| 20        | NewYork FC   |
| 30        | Atlanta FC   |
| 40        | Chicago FC   |
| 50        | Toronto FC   |
+-----------+--------------+

Matches table:
+------------+--------------+---------------+-------------+--------------+
| match_id   | host_team    | guest_team    | host_goals  | guest_goals  |
+------------+--------------+---------------+-------------+--------------+
| 1          | 10           | 20            | 3           | 0            |
| 2          | 30           | 10            | 2           | 2            |
| 3          | 10           | 50            | 5           | 1            |
| 4          | 20           | 30            | 1           | 0            |
| 5          | 50           | 30            | 1           | 0            |
+------------+--------------+---------------+-------------+--------------+

Result table:
+------------+--------------+---------------+
| team_id    | team_name    | num_points    |
+------------+--------------+---------------+
| 10         | Leetcode FC  | 7             |
| 20         | NewYork FC   | 3             |
| 50         | Toronto FC   | 3             |
| 30         | Atlanta FC   | 1             |
| 40         | Chicago FC   | 0             |
+------------+--------------+---------------+
--我的寫法,讀懂題意
select
Teams.team_id team_id,team_name, ifnull(num_points,0) as num_points 
from 
Teams left join 
(
select 
team_id,sum(points) as num_points 
from 
(
select 
host_team as team_id,sum(case when host_goals > guest_goals  then 3 when host_goals < guest_goals then 0 else 1 end ) as points 
from
Matches
group by host_team
union all 
select 
guest_team  ,sum(case when host_goals > guest_goals  then 0 when host_goals < guest_goals then 3 else 1 end ) 
from
Matches
group by guest_team 
) t1
group by  team_id
) t2 
on Teams.team_id = t2.team_id
order by num_points desc  ,team_id 
--評(píng)論區(qū)寫法
select t.team_id,t.team_name,
        ifnull(sum(case when m.host_goals>m.guest_goals and t.team_id=m.host_team then 3 
                        when m.host_goals=m.guest_goals and t.team_id=m.host_team then 1
                        when m.host_goals<m.guest_goals and t.team_id=m.host_team then 0
                        when m.host_goals>m.guest_goals and t.team_id=m.guest_team then 0
                        when m.host_goals=m.guest_goals and t.team_id=m.guest_team then 1
                        when m.host_goals<m.guest_goals and t.team_id=m.guest_team then 3
                   end),0) as num_points
from Teams t,Matches m
group by t.team_id
order by num_points desc,t.team_id asc

79.報(bào)告系統(tǒng)狀態(tài)的連續(xù)日期

編寫一個(gè) SQL 查詢 2019-01-01 到 2019-12-31 期間任務(wù)連續(xù)同狀態(tài) period_state 的起止日期(start_date 和 end_date)。即如果任務(wù)失敗了,就是失敗狀態(tài)的起止日期,如果任務(wù)成功了,就是成功狀態(tài)的起止日期。

Table: Failed

+--------------+---------+
| Column Name  | Type    |
+--------------+---------+
| fail_date    | date    |
+--------------+---------+
該表主鍵為 fail_date。
該表包含失敗任務(wù)的天數(shù).
Table: Succeeded

+--------------+---------+
| Column Name  | Type    |
+--------------+---------+
| success_date | date    |
+--------------+---------+
該表主鍵為 success_date。
該表包含成功任務(wù)的天數(shù).
 

系統(tǒng) 每天 運(yùn)行一個(gè)任務(wù)。每個(gè)任務(wù)都獨(dú)立于先前的任務(wù)。任務(wù)的狀態(tài)可以是失敗或是成功。

編寫一個(gè) SQL 查詢 2019-01-01 到 2019-12-31 期間任務(wù)連續(xù)同狀態(tài) period_state 的起止日期(start_date 和 end_date)。即如果任務(wù)失敗了,就是失敗狀態(tài)的起止日期,如果任務(wù)成功了,就是成功狀態(tài)的起止日期。

最后結(jié)果按照起始日期 start_date 排序

查詢結(jié)果樣例如下所示:

Failed table:
+-------------------+
| fail_date         |
+-------------------+
| 2018-12-28        |
| 2018-12-29        |
| 2019-01-04        |
| 2019-01-05        |
+-------------------+

Succeeded table:
+-------------------+
| success_date      |
+-------------------+
| 2018-12-30        |
| 2018-12-31        |
| 2019-01-01        |
| 2019-01-02        |
| 2019-01-03        |
| 2019-01-06        |
+-------------------+


Result table:
+--------------+--------------+--------------+
| period_state | start_date   | end_date     |
+--------------+--------------+--------------+
| succeeded    | 2019-01-01   | 2019-01-03   |
| failed       | 2019-01-04   | 2019-01-05   |
| succeeded    | 2019-01-06   | 2019-01-06   |
+--------------+--------------+--------------+

結(jié)果忽略了 2018 年的記錄,因?yàn)槲覀冎魂P(guān)心從 2019-01-01 到 2019-12-31 的記錄
從 2019-01-01 到 2019-01-03 所有任務(wù)成功,系統(tǒng)狀態(tài)為 "succeeded"。
從 2019-01-04 到 2019-01-05 所有任務(wù)失敗,系統(tǒng)狀態(tài)為 "failed"。
從 2019-01-06 到 2019-01-06 所有任務(wù)成功,系統(tǒng)狀態(tài)為 "succeeded"。
--終于跑對(duì)了,Oracle真麻煩
select
'succeeded' as period_state ,to_char(min(success_date),'yyyy-mm-dd') as start_date,
to_char(max(success_date),'yyyy-mm-dd') as end_date
from 
(
select
success_date,
(success_date - row_number() over(order by success_date) ) rn 
from
Succeeded
where to_char(success_date,'yyyy-mm-dd') >= '2019-01-01'  and to_char(success_date,'yyyy-mm-dd') <=  '2019-12-31'
)
group by rn 
union all 
select
'failed',to_char(min(fail_date),'yyyy-mm-dd'),to_char(max(fail_date),'yyyy-mm-dd')
from 
(
select
fail_date,
( fail_date   - row_number() over(order by  fail_date  ) ) rn 
from
Failed
where to_char(fail_date,'yyyy-mm-dd') between '2019-01-01'  and  '2019-12-31'
) 
group by rn 
order by start_date
-- 整體求,注意不要排序簡(jiǎn)單的連續(xù)登陸案例變形題
select state as period_state,min(dt) as start_date,max(dt) as end_date 
from
(
    select *,subdate(dt,rank() over(partition by state order by dt)) as dif 
    from
    (
        select 'failed' as state,fail_date as dt from failed where fail_date between '2019-01-01' and '2019-12-31'
    union all
        select 'succeeded' as state,success_date as dt from succeeded where success_date between '2019-01-01' and '2019-12-31'
     )t1 
)t2
group by state,dif
order by dt

80.每個(gè)帖子的評(píng)論數(shù)

編寫 SQL 語(yǔ)句以查找每個(gè)帖子的評(píng)論數(shù)。
結(jié)果表應(yīng)包含帖子的 post_id 和對(duì)應(yīng)的評(píng)論數(shù) number_of_comments 并且按 post_id 升序排列。
Submissions 可能包含重復(fù)的評(píng)論。您應(yīng)該計(jì)算每個(gè)帖子的唯一評(píng)論數(shù)。
Submissions 可能包含重復(fù)的帖子。您應(yīng)該將它們視為一個(gè)帖子。

表 Submissions 結(jié)構(gòu)如下:

+---------------+----------+
| 列名           | 類型     |
+---------------+----------+
| sub_id        | int      |
| parent_id     | int      |
+---------------+----------+
上表沒有主鍵, 所以可能會(huì)出現(xiàn)重復(fù)的行。
每行可以是一個(gè)帖子或?qū)υ撎拥脑u(píng)論。
如果是帖子的話,parent_id 就是 null。
對(duì)于評(píng)論來說,parent_id 就是表中對(duì)應(yīng)帖子的 sub_id。
 

編寫 SQL 語(yǔ)句以查找每個(gè)帖子的評(píng)論數(shù)。

結(jié)果表應(yīng)包含帖子的 post_id 和對(duì)應(yīng)的評(píng)論數(shù) number_of_comments 并且按 post_id 升序排列。

Submissions 可能包含重復(fù)的評(píng)論。您應(yīng)該計(jì)算每個(gè)帖子的唯一評(píng)論數(shù)。

Submissions 可能包含重復(fù)的帖子。您應(yīng)該將它們視為一個(gè)帖子。

查詢結(jié)果格式如下例所示:

Submissions table:
+---------+------------+
| sub_id  | parent_id  |
+---------+------------+
| 1       | Null       |
| 2       | Null       |
| 1       | Null       |
| 12      | Null       |
| 3       | 1          |
| 5       | 2          |
| 3       | 1          |
| 4       | 1          |
| 9       | 1          |
| 10      | 2          |
| 6       | 7          |
+---------+------------+

結(jié)果表:
+---------+--------------------+
| post_id | number_of_comments |
+---------+--------------------+
| 1       | 3                  |
| 2       | 2                  |
| 12      | 0                  |
+---------+--------------------+

表中 ID 為 1 的帖子有 ID 為 3、4 和 9 的三個(gè)評(píng)論。表中 ID 為 3 的評(píng)論重復(fù)出現(xiàn)了,所以我們只對(duì)它進(jìn)行了一次計(jì)數(shù)。
表中 ID 為 2 的帖子有 ID 為 5 和 10 的兩個(gè)評(píng)論。
ID 為 12 的帖子在表中沒有評(píng)論。
表中 ID 為 6 的評(píng)論是對(duì) ID 為 7 的已刪除帖子的評(píng)論,因此我們將其忽略。
-- 簡(jiǎn)單題
select
a.sub_id as post_id ,ifnull(count(distinct b.sub_id ),0) as  number_of_comments
from 
(
select
distinct sub_id as sub_id
from
Submissions
where parent_id is null
) a 
left join 
Submissions b
on a.sub_id = b.parent_id
group by a.sub_id
select s1.sub_id post_id, count(distinct s2.sub_id) number_of_comments
from 
submissions s1 left join submissions s2 on s1.sub_id = s2.parent_id
where s1.parent_id is null
group by s1.sub_id
order by 1

一個(gè)基礎(chǔ)題left join on 和 left join where 的區(qū)別,left join on 無(wú)論是否滿足都會(huì)返回左邊的數(shù)據(jù)

https://www.cnblogs.com/leochenliang/p/7364665.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容