Day1 選擇 595. 大的國家 World表: + + + | Column Name | Type | + + + | name | varchar | | continent | varchar | | area | int | | population | int | | gdp | in ...
Day1 選擇
595. 大的國家
World表:
+-------------+---------+
| Column Name | Type |
+-------------+---------+
| name | varchar |
| continent | varchar |
| area | int |
| population | int |
| gdp | int |
+-------------+---------+
name 是這張表的主鍵。
這張表的每一行提供:國家名稱、所屬大陸、面積、人口和 GDP 值
選擇出:
- 面積至少為 300 萬平方公裡(即,\(3000000\ km^2\)),或者
- 人口至少為 2500 萬(即 \(25000000\))
方法一
兩個條件一起查詢:
select name, population, area
from World
where area >= 3000000 or population >= 25000000;
方法二
使用union連接兩個查詢條件:
select name, population, area
from world
where area >= 3000000
union
select name, population, area
from world
where population >= 25000000;
Union:對兩個結果集進行並集操作,不包括重覆行,同時進行預設規則的排序; 即:去重+排序
Union All:對兩個結果集進行並集操作,包括重覆行,不進行排序; 即:不去重+不排序
1757. 可回收且低脂的產品
Products表:
+-------------+---------+
| Column Name | Type |
+-------------+---------+
| product_id | int |
| low_fats | enum |
| recyclable | enum |
+-------------+---------+
product_id 是這個表的主鍵。
low_fats 是枚舉類型,取值為以下兩種 ('Y', 'N'),其中 'Y' 表示該產品是低脂產品,'N' 表示不是低脂產品。
recyclable 是枚舉類型,取值為以下兩種 ('Y', 'N'),其中 'Y' 表示該產品可回收,而 'N' 表示不可回收。
select product_id
from products
where low_fats = 'Y' and recyclable = 'Y';
584. 尋找用戶推薦人
+------+------+-----------+
| id | name | referee_id|
+------+------+-----------+
| 1 | Will | NULL |
| 2 | Jane | NULL |
| 3 | Alex | 2 |
| 4 | Bill | NULL |
| 5 | Zack | 1 |
| 6 | Mark | 2 |
+------+------+-----------+
MySQL有三個邏輯值:TRUE, FALSE, NULL
所以這個題如果直接選擇 referee_id != 2
,則會導致 referee_id = NULL
的數據沒有被選擇出來,所以要加上 referee_id is null
select name
from customer
where referee_id != 2 or referee_id is null;
還有一種方法是先選出來編號為2的元素然後取反:
<=>
運算符相當於封裝了= 和 is ,既可以判斷 非NULL值,也可以用來判斷NULL值。只能在MySQL中使用
select name
from customer
where not referee_id <=> 2;
或者使用 not in
:
select name
from customer
where id not in (select id from customer where referee_id = 2);
# id是主鍵,所以選擇referee_id等於2的id然後取反
183. 從不訂購的客戶
Customers 表:
+----+-------+
| Id | Name |
+----+-------+
| 1 | Joe |
| 2 | Henry |
| 3 | Sam |
| 4 | Max |
+----+-------+
Orders 表:
+----+------------+
| Id | CustomerId |
+----+------------+
| 1 | 3 |
| 2 | 1 |
+----+------------+
註意要對name重命名為Customers
select customers.name as 'Customers'
from customers
where customers.id not in(select CustomerId from orders);
使用左連接
select Customers.name as 'Customers'
from Customers
left join orders
on Customers.id = orders.CustomerId
where orders.CustomerId is null;
Day2 排序&修改
1873. 計算特殊獎金
Employees表:
+-------------+---------+
| 列名 | 類型 |
+-------------+---------+
| employee_id | int |
| name | varchar |
| salary | int |
+-------------+---------+
employee_id 是這個表的主鍵。
此表的每一行給出了雇員id ,名字和薪水。
使用CASE
case配合when,then
when後面是條件,then後面是返回的結果
select employee_id,
(
case
when mod(employee_id, 2) != 0 and left(name, 1) != 'M' then salary
else 0
end
) as bonus
from Employees
order by employee_id;
使用IF
IF有三個參數,第一個是判斷條件,第二個是條件成立的返回值,第三個是條件不成立的返回值
select employee_id,
if(mod(employee_id, 2) != 0 and left(name, 1) != 'M', salary, 0) as bonus
from Employees
order by employee_id;
使用LIKE
使用LIKE進行匹配:
'%a' //以a結尾的數據
'a%' //以a開頭的數據
'%a%' //含有a的數據
'_a_' //三位且中間字母是a的
'_a' //兩位且結尾字母是a的
'a_' //兩位且開頭字母是a的
select employee_id,
if(mod(employee_id, 2) = 0 or name like 'M%', 0, salary) as bonus
from Employees
order by employee_id;
627. 變更性別
要求只使用單個 update 語句 ,且不產生中間臨時表。
Salary 表:
+-------------+----------+
| Column Name | Type |
+-------------+----------+
| id | int |
| name | varchar |
| sex | ENUM |
| salary | int |
+-------------+----------+
id 是這個表的主鍵。
sex 這一列的值是 ENUM 類型,只能從 ('m', 'f') 中取。
本表包含公司雇員的信息。
使用IF
update Salary
set sex = if(sex = 'f', 'm', 'f');
使用CASE
update Salary
set sex =
case
when sex = 'f' then 'm'
else 'f'
end;
196. 刪除重覆的電子郵箱
題目要求不使用SELECT語句
Person表:
+-------------+---------+
| Column Name | Type |
+-------------+---------+
| id | int |
| email | varchar |
+-------------+---------+
id是該表的主鍵列。
該表的每一行包含一封電子郵件。電子郵件將不包含大寫字母。
delete p1
表示從p1表中刪除滿足where條件的記錄
# Please write a DELETE statement and DO NOT write a SELECT statement.
# Write your MySQL query statement below
delete p1
from Person p1, Person p2
where p1.email = p2.email and p1.id > p2.id;
使用SELECT和GROUP BY:
delete from Person
where id not in(
select * from(select min(id) from Person group by email) t
);
Day3 字元串處理函數/正則
1667. 修複表中的名字
Users表:
+----------------+---------+
| Column Name | Type |
+----------------+---------+
| user_id | int |
| name | varchar |
+----------------+---------+
user_id 是該表的主鍵。
該表包含用戶的 ID 和名字。名字僅由小寫和大寫字元組成。
CONCAT
函數用來拼接兩個字元串,使用 UPPER
和 LOWER
來對name進行變換,然後拼接起來
select user_id, concat(upper(left(name, 1)), lower(substring(name, 2))) as name
from Users
order by user_id;
1484. 按日期分組銷售產品
Activities表:
+-------------+---------+
| 列名 | 類型 |
+-------------+---------+
| sell_date | date |
| product | varchar |
+-------------+---------+
此表沒有主鍵,它可能包含重覆項。
此表的每一行都包含產品名稱和在市場上銷售的日期。
用 group by sell_date
將產品按日期統計起來,然後使用 count
進行計數,使用 group_concat
將產品名拼接起來
select sell_date,
count(distinct(product)) as num_sold,
group_concat(distinct product order by product asc separator ',') as products
from Activities
group by sell_date;
1527. 患某種疾病的患者
患者信息表: Patients
+--------------+---------+
| Column Name | Type |
+--------------+---------+
| patient_id | int |
| patient_name | varchar |
| conditions | varchar |
+--------------+---------+
patient_id (患者 ID)是該表的主鍵。
'conditions' (疾病)包含 0 個或以上的疾病代碼,以空格分隔。
這個表包含醫院中患者的信息。
用like匹配,註意兩種情況:
DIAB1
在第一個,這時候用DIAN1%
匹配DIAB1
不在第一個,此時要在用% DIAB1%
匹配,註意前面有個空格
select patient_id, patient_name, conditions
from Patients
where conditions like 'DIAB1%' or conditions like '% DIAB1%';
Day4 組合查詢 & 指定選取
1965. 丟失信息的雇員
表: 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 和他的薪水。
使用 union all
來連接兩個查詢結果,通過 group by
進行將employee_id進行聚合,使用 having count()
選擇僅出現一次的id
UNION
和 UNION ALL
的區別:前者會在連接後進行去重操作;後者不會去重,把查詢出來的所有結果一起返回
select employee_id
from(
select employee_id from Employees
union all
select employee_id from Salaries
) as t
group by employee_id
having count(*) = 1
order by employee_id asc;
1795. 每個產品在不同商店的價格
表:Products
+-------------+---------+
| Column Name | Type |
+-------------+---------+
| product_id | int |
| store1 | int |
| store2 | int |
| store3 | int |
+-------------+---------+
這張表的主鍵是product_id(產品Id)。
每行存儲了這一產品在不同商店store1, store2, store3的價格。
如果這一產品在商店裡沒有出售,則值將為null。
將查詢出來的 store{1,2,3}
都重命名為 store
,然後使用 union
將三個查詢連接起來
select product_id, 'store1' as store, store1 price from Products where store1 is not null
union
select product_id, 'store2' as store, store2 price from Products where store2 is not null
union
select product_id, 'store3' as store, store3 price from Products where store3 is not null;
608. 樹節點
給定一個表 tree,id 是樹節點的編號, p_id 是它父節點的 id 。
+----+------+
| id | p_id |
+----+------+
| 1 | null |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
| 5 | 2 |
+----+------+
使用CASE
如果 p_id
為null,則節點為根節點
如果 id
在 p_id
里出現過,則為內部節點
沒出現過的為葉子
select t.id, (
case
when t.p_id is null then 'Root'
when (
select count(*)
from tree t1 where t1.p_id = t.id
) > 0 then 'Inner'
else 'Leaf'
end
) as type
from tree as t;
使用LEFT JOIN
將 id
與 p_id
進行左連接
如果 t1.p_id
是空,則該節點是根節點
如果 t2.p_id
是空,則說明 id
沒有在 p_id
中出現過,即該節點是葉子
否則,是內部節點
select distinct t1.id, (
if(isnull(t1.p_id), 'Root', if(isnull(t2.p_id), 'Leaf', 'Inner'))
) as type
from tree t1
left join
tree t2 on t1.id = t2.p_id;
176. 第二高的薪水
Employee 表:
+-------------+------+
| Column Name | Type |
+-------------+------+
| id | int |
| salary | int |
+-------------+------+
id 是這個表的主鍵。
表的每一行包含員工的工資信息。
方法二和方法三註意使用 DISTINCT
去重,因為最高的薪水可能不止一個
方法一
從去除掉最大薪水的剩餘表中查詢最大薪水
select max(salary) as SecondHighestSalary
from Employee
where salary not in (select max(salary) from Employee);
方法二
使用 limit
和 offset
offset
表示要跳過的數據的數量
如果查詢到的數據為空,用 ifnull
將空數據變為null
select ifnull
(
(
select distinct salary
from Employee
order by salary desc
limit 1 offset 1
), null
) as SecondHighestSalary;
方法三
使用臨時表解決沒有第二高工資的情況,對臨時表進行選擇,如果臨時表是空表的話會返回null
select(
select distinct salary
from Employee
order by salary desc
limit 1 offset 1
) as SecondHighestSalary;
Day5 合併
LEFT JOIN
從左表(table1)返回所有的行,即使右表(table2)中沒有匹配。如果右表中沒有匹配,則結果為 NULL。
語法示例:
SELECT column_name(s)
FROM table1
LEFT JOIN table2
ON table1.column_name=table2.column_name;
175. 組合兩個表
表: Person
+-------------+---------+
| 列名 | 類型 |
+-------------+---------+
| PersonId | int |
| FirstName | varchar |
| LastName | varchar |
+-------------+---------+
personId 是該表的主鍵列。
該表包含一些人的 ID 和他們的姓和名的信息。
表: Address
+-------------+---------+
| 列名 | 類型 |
+-------------+---------+
| AddressId | int |
| PersonId | int |
| City | varchar |
| State | varchar |
+-------------+---------+
addressId 是該表的主鍵列。
該表的每一行都包含一個 ID = PersonId 的人的城市和州的信息。
直接使用左連接即可
select firstName, lastName, city, state
from Person
left join Address
on Person.personId = Address.personId;
1581. 進店卻未進行過交易的顧客
表: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 期間進行的交易的信息。
使用左連接將 Visits
表和 Transactions
表連接,然後查詢連接後的表裡有多少個null
select customer_id, count(*) 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;
1148. 文章瀏覽 I
Views 表:
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| article_id | int |
| author_id | int |
| viewer_id | int |
| view_date | date |
+---------------+---------+
此表無主鍵,因此可能會存在重覆行。
此表的每一行都表示某人在某天瀏覽了某位作者的某篇文章。
請註意,同一人的 author_id 和 viewer_id 是相同的。
使用 DISTINCT
或 GROUP BY
均可
select distinct author_id as id
from Views
where author_id = viewer_id
# group by id
order by id asc;
Day6 合併
197. 上升的溫度
表: Weather
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| id | int |
| recordDate | date |
| temperature | int |
+---------------+---------+
id 是這個表的主鍵
該表包含特定日期的溫度信息
使用 DATEDIFF
函數來判斷兩個日期的差值
可以使用 INNER JOIN
連接,也可以直接select兩個表:
select today.id
from
Weather today,
Weather yesterday
# 或者:
# Weather today
# inner join Weather yesterday
where datediff(today.recordDate, yesterday.recordDate) = 1 and today.Temperature > yesterday.Temperature;
607. 銷售員
表: SalesPerson
+-----------------+---------+
| Column Name | Type |
+-----------------+---------+
| sales_id | int |
| name | varchar |
| salary | int |
| commission_rate | int |
| hire_date | date |
+-----------------+---------+
sales_id 是該表的主鍵列。
該表的每一行都顯示了銷售人員的姓名和 ID ,以及他們的工資、佣金率和雇佣日期。
使用 WHERE
一直嵌套
select S.name as name
from SalesPerson S
where S.sales_id not in
(
select O.sales_id
from Orders O
where O.com_id in
(
select C.com_id
from Company C
where C.name = 'RED'
)
);
1141. 查詢近30天活躍用戶數
活動記錄表:Activity
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| user_id | int |
| session_id | int |
| activity_date | date |
| activity_type | enum |
+---------------+---------+
該表是用戶在社交網站的活動記錄。
該表沒有主鍵,可能包含重覆數據。
activity_type 欄位為以下四種值 ('open_session', 'end_session', 'scroll_down', 'send_message')。
每個 session_id 只屬於一個用戶。
註意是 distinct user_id
,因為 一個用戶可能會對應多個 session_id
,datediff
的時候要註意不小於0
select activity_date as day, count(distinct user_id) as active_users
from Activity
where datediff('2019-07-27', activity_date) < 30 and datediff('2019-07-27', activity_date) >= 0
group by activity_date;
Day7 統計去重
1141. 查詢近30天活躍用戶數
活動記錄表:Activity
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| user_id | int |
| session_id | int |
| activity_date | date |
| activity_type | enum |
+---------------+---------+
該表是用戶在社交網站的活動記錄。
該表沒有主鍵,可能包含重覆數據。
activity_type 欄位為以下四種值 ('open_session', 'end_session', 'scroll_down', 'send_message')。
每個 session_id 只屬於一個用戶。
註意是 distinct user_id
,因為 一個用戶可能會對應多個 session_id
,datediff
的時候要註意不小於0
select activity_date as day, count(distinct user_id) as active_users
from Activity
where datediff('2019-07-27', activity_date) < 30 and datediff('2019-07-27', activity_date) >= 0
group by activity_date;
1693. 每天的領導和合伙人
表:DailySales
+-------------+---------+
| Column Name | Type |
+-------------+---------+
| date_id | date |
| make_name | varchar |
| lead_id | int |
| partner_id | int |
+-------------+---------+
該表沒有主鍵。
該表包含日期、產品的名稱,以及售給的領導和合伙人的編號。
名稱只包含小寫英文字母。
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;
1729. 求關註者的數量
表: Followers
+-------------+------+
| Column Name | Type |
+-------------+------+
| user_id | int |
| follower_id | int |
+-------------+------+
(user_id, follower_id) 是這個表的主鍵。
該表包含一個關註關係中關註者和用戶的編號,其中關註者關註用戶。
select user_id, count(follower_id) as followers_count
from Followers
group by user_id
order by user_id asc;
Day8 計算函數
586. 訂單最多的客戶
表: Orders
+-----------------+----------+
| Column Name | Type |
+-----------------+----------+
| order_number | int |
| customer_number | int |
+-----------------+----------+
Order_number是該表的主鍵。
此表包含關於訂單ID和客戶ID的信息。
降序排序後用 limit 1
選擇出來第一個值,就是訂單最多的用戶
select customer_number
from Orders
group by customer_number
order by count(*) desc
limit 1;
511. 游戲玩法分析 I
活動表 Activity:
+--------------+---------+
| Column Name | Type |
+--------------+---------+
| player_id | int |
| device_id | int |
| event_date | date |
| games_played | int |
+--------------+---------+
表的主鍵是 (player_id, event_date)。
這張表展示了一些游戲玩家在游戲平臺上的行為活動。
每行數據記錄了一名玩家在退出平臺之前,當天使用同一臺設備登錄平臺後打開的游戲的數目(可能是 0 個)。
對 player_id
進行分組,然後選擇出每個id的最小的 event_date
使用排序後時間會比不用排序直接去最小值快將近100ms,chatgpt給出的解釋是:
MySQL 中先排序再取最小值可能會變快的原因是,在數據表中有索引的情況下,如果在排序之前就取最小值,MySQL 的引擎會掃描整個表併在記憶體中對所有行進行排序,而如果先排序再取最小值,MySQL 的引擎只需要掃描索引並返回第一個索引值即可。
這個表現差異更明顯的是在排序欄位上有索引的情況下.
在這種情況下,MySQL 的引擎可以使用索引進行排序,而無需在記憶體中對所有行進行排序。因此查詢速度會顯著加快.
select player_id, min(event_date) as first_login
from Activity
group by player_id
order by event_date asc;
1890. 2020年最後一次登錄
表: Logins
+----------------+----------+
| 列名 | 類型 |
+----------------+----------+
| user_id | int |
| time_stamp | datetime |
+----------------+----------+
(user_id, time_stamp) 是這個表的主鍵。
每一行包含的信息是user_id 這個用戶的登錄時間。
對 user_id
進行分組,選出在2020年的最大登錄時間
select user_id, max(time_stamp) as last_stamp
from Logins
where time_stamp between '2020-01-01 0:0:0' and '2020-12-31 23:59:59'
group by user_id;
1741. 查找每個員工花費的總時間
表: Employees
+-------------+------+
| Column Name | Type |
+-------------+------+
| emp_id | int |
| event_day | date |
| in_time | int |
| out_time | int |
+-------------+------+
(emp_id, event_day, in_time) 是這個表的主鍵。
該表顯示了員工在辦公室的出入情況。
event_day 是此事件發生的日期,in_time 是員工進入辦公室的時間,而 out_time 是他們離開辦公室的時間。
in_time 和 out_time 的取值在1到1440之間。
題目保證同一天沒有兩個事件在時間上是相交的,並且保證 in_time 小於 out_time。
select event_day as day, emp_id, sum(out_time - in_time) as total_time
from Employees
group by emp_id, event_day;
Day9 控制流
1393. 股票的資本損益
Stocks 表:
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| stock_name | varchar |
| operation | enum |
| operation_day | int |
| price | int |
+---------------+---------+
(stock_name, day) 是這張表的主鍵
operation 列使用的是一種枚舉類型,包括:('Sell','Buy')
此表的每一行代表了名為 stock_name 的某支股票在 operation_day 這一天的操作價格。
保證股票的每次'Sell'操作前,都有相應的'Buy'操作。
用 if
判斷一下,用 case
也可以
select stock_name, sum(
if(operation = 'Buy', -1 * price, price)
) as capital_gain_loss
from Stocks
group by stock_name;
1407. 排名靠前的旅行者
表:Users
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| id | int |
| name | varchar |
+---------------+---------+
id 是該表單主鍵。
name 是用戶名字。
用 ifnull
來將null變為0,order by
可以排序多個欄位
select name, ifnull(sum(distance), 0) as travelled_distance
from Users
left join
Rides on Users.id = Rides.user_id
group by user_id
order by travelled_distance desc, name asc;
1158. 市場分析 I
Table: Users
+----------------+---------+
| Column Name | Type |
+----------------+---------+
| user_id | int |
| join_date | date |
| favorite_brand | varchar |
+----------------+---------+
此表主鍵是 user_id。
表中描述了購物網站的用戶信息,用戶可以在此網站上進行商品買賣。
Table: Orders
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| order_id | int |
| order_date | date |
| item_id | int |
| buyer_id | int |
| seller_id | int |
+---------------+---------+
此表主鍵是 order_id。
外鍵是 item_id 和(buyer_id,seller_id)。
Table: Items
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| item_id | int |
| item_brand | varchar |
+---------------+---------+
此表主鍵是 item_id。
Items
表是沒有用的。
首先從 Orders
表中選出在2019年買過商品的 buyer_id
,然後用 group by
分組,統計出來每個人買的次數,然後和 Users
表進行連接
select user_id as buyer_id, join_date, ifnull(orders_in_2019, 0) as orders_in_2019
from Users as U
left join(
select buyer_id, count(*) as orders_in_2019
from Orders as O
where O.order_date between '2019-01-01' and '2019-12-31'
group by buyer_id
) as t
on t.buyer_id = U.user_id;
Day10 過濾
182. 查找重覆的電子郵箱
編寫一個 SQL 查詢,查找 Person 表中所有重覆的電子郵箱。
示例:
+----+---------+
| Id | Email |
+----+---------+
| 1 | [email protected] |
| 2 | [email protected] |
| 3 | [email protected] |
+----+---------+
使用GROUP BY
select Email
from(
select Email, count(*) as cnt
from Person
group by Email
) as t
where t.cnt > 1;
使用GROUP BY和HAVING
select Email
from Person
group by Email
having count(*) > 1;
1050. 合作過至少三次的演員和導演
ActorDirector 表:
+-------------+---------+
| Column Name | Type |
+-------------+---------+
| actor_id | int |
| director_id | int |
| timestamp | int |
+-------------+---------+
timestamp 是這張表的主鍵.
使用GROUP BY和HAVING
select actor_id, director_id
from ActorDirector
group by actor_id, director_id
having count(*) >= 3;
1587. 銀行賬戶概要 II
表: Users
+--------------+---------+
| Column Name | Type |
+--------------+---------+
| account | int |
| name | varchar |
+--------------+---------+
account 是該表的主鍵.
表中的每一行包含銀行里中每一個用戶的賬號.
表: Transactions
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| trans_id | int |
| account | int |
| amount | int |
| transacted_on | date |
+---------------+---------+
trans_id 是該表主鍵.
該表的每一行包含了所有賬戶的交易改變情況.
如果用戶收到了錢, 那麼金額是正的; 如果用戶轉了錢, 那麼金額是負的.
所有賬戶的起始餘額為 0.
使用左連接將兩個表連接起來,然後對 account
進行分組,計算賬戶餘額,最後用 having
選出餘額大於一萬的賬戶
select name,sum(amount) as balance
from Users as U
left join
Transactions as T
on U.account = T.account
group by T.account
having balance > 10000;
1084. 銷售分析III
Table: Product
+--------------+---------+
| Column Name | Type |
+--------------+---------+
| product_id | int |
| product_name | varchar |
| unit_price | int |
+--------------+---------+
Product_id是該表的主鍵。
該表的每一行顯示每個產品的名稱和價格。
Table: Sales
+-------------+---------+
| Column Name | Type |
+-------------+---------+
| seller_id | int |
| product_id | int |
| buyer_id | int |
| sale_date | date |
| quantity | int |
| price | int |
+------ ------+---------+
這個表沒有主鍵,它可以有重覆的行。
product_id 是 Product 表的外鍵。
該表的每一行包含關於一個銷售的一些信息。
註意是產品的所有銷售時間都在第一個季度,所以要判斷銷售時間的最大值和最小值均在第一季度
select P.product_id, P.product_name
from Product as P
left join
Sales as S on S.product_id = P.product_id
group by S.product_id
having (min(S.sale_date) between '2019-01-01' and '2019-03-31') and (max(S.sale_date) between '2019-01-01' and '2019-03-31')