175. Combine Two Tables
Table: Person
+-------------+---------+ | Column Name | Type | +-------------+---------+ | PersonId | int | | FirstName | varchar | | LastName | varchar | +-------------+---------+ PersonId is the primary key column for this table.
Table: Address
+-------------+---------+ | Column Name | Type | +-------------+---------+ | AddressId | int | | PersonId | int | | City | varchar | | State | varchar | +-------------+---------+ AddressId is the primary key column for this table.
Write a SQL query for a report that provides the following information for each person in the Person table, regardless if there is an address for each of those people:
FirstName, LastName, City, State
select
p.FirstName, p.LastName, a.City, a.State
from
Person p left join Address a on p.PersonId = a.PersonId ;
176. second highest salary
Write a SQL query to get the second highest salary from the Employee
table.
+----+--------+ | Id | Salary | +----+--------+ | 1 | 100 | | 2 | 200 | | 3 | 300 | +----+--------+
For example, given the above Employee table, the query should return 200
as the second highest salary. If there is no second highest salary, then the query should return null
.
+---------------------+ | SecondHighestSalary | +---------------------+ | 200 | +---------------------+
IFNULL(expr1,expr2) 如果 expr1 不是 NULL,IFNULL() 返回 expr1,否则它返回 expr2。
select ... as sth; 这个指的是生成一个列名
# Write your MySQL query statement below
#distinct,order by 和limit 组合使用
select IFNULL(
(select distinct Salary from Employee order by Salary desc
limit 1, 1),
NULL
) as SecondHighestSalary;
CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
BEGIN
declare n1 int;
set n1=N-1;
RETURN (
# Write your MySQL query statement below.
select distinct Salary from Employee order by Salary desc limit n1,1
);
END
178. Rank Scores
Write a SQL query to rank scores. If there is a tie between two scores, both should have the same ranking. Note that after a tie, the next ranking number should be the next consecutive integer value. In other words, there should be no "holes" between ranks.
+----+-------+ | Id | Score | +----+-------+ | 1 | 3.50 | | 2 | 3.65 | | 3 | 4.00 | | 4 | 3.85 | | 5 | 4.00 | | 6 | 3.65 | +----+-------+
For example, given the above Scores
table, your query should generate the following report (order by highest score):
+-------+------+ | Score | Rank | +-------+------+ | 4.00 | 1 | | 4.00 | 1 | | 3.85 | 2 | | 3.65 | 3 | | 3.65 | 3 | | 3.50 | 4 | +-------+------+
select
Score,
(select count(distinct b.Score) from Scores b where b.Score >= s.Score) as Rank
from Scores s
order by Score desc
Write a SQL query to find all numbers that appear at least three times consecutively.
+----+-----+ | Id | Num | +----+-----+ | 1 | 1 | | 2 | 1 | | 3 | 1 | | 4 | 2 | | 5 | 1 | | 6 | 2 | | 7 | 2 | +----+-----+
For example, given the above Logs
table, 1
is the only number that appears consecutively for at least three times.
+-----------------+ | ConsecutiveNums | +-----------------+ | 1 | +-----------------+
select distinct l1.Num as ConsecutiveNums
from Logs l1, Logs l2, Logs l3
where l1.Id=l2.Id-1 and l2.Id=l3.Id-1 and l1.Num = l2.Num and l2.Num = l3.Num;
The Employee
table holds all employees including their managers. Every employee has an Id, and there is also a column for the manager Id.
+----+-------+--------+-----------+ | Id | Name | Salary | ManagerId | +----+-------+--------+-----------+ | 1 | Joe | 70000 | 3 | | 2 | Henry | 80000 | 4 | | 3 | Sam | 60000 | NULL | | 4 | Max | 90000 | NULL | +----+-------+--------+-----------+
Given the Employee
table, write a SQL query that finds out employees who earn more than their managers. For the above table, Joe is the only employee who earns more than his manager.
+----------+ | Employee | +----------+ | Joe | +----------+
select
a.name as Employee
from
Employee a, Employee b
where
a.ManagerId = b.Id and a.Salary > b.Salary;
Write a SQL query to find all duplicate emails in a table named Person
.
+----+---------+ | Id | Email | +----+---------+ | 1 | a@b.com | | 2 | c@d.com | | 3 | a@b.com | +----+---------+
For example, your query should return the following for the above table:
+---------+ | Email | +---------+ | a@b.com | +---------+
Note: All emails are in lowercase.
select
distinct a.Email as Email
from
Person a, Person b
where
a.Email = b.Email and a.Id != b.Id;
183. Customers Who Never Order
Suppose that a website contains two tables, the Customers
table and the Orders
table. Write a SQL query to find all customers who never order anything.
Table: Customers
.
+----+-------+ | Id | Name | +----+-------+ | 1 | Joe | | 2 | Henry | | 3 | Sam | | 4 | Max | +----+-------+
Table: Orders
.
+----+------------+ | Id | CustomerId | +----+------------+ | 1 | 3 | | 2 | 1 | +----+------------+
Using the above tables as example, return the following:
+-----------+ | Customers | +-----------+ | Henry | | Max | +-----------+
这种很常见,一个值在a中,不在b中,就用 not in
select c.Name as Customers
from Customers c
where c.Id not in (select CustomerId from Orders) ;
The Employee
table holds all employees. Every employee has an Id, a salary, and there is also a column for the department Id.
+----+-------+--------+--------------+ | Id | Name | Salary | DepartmentId | +----+-------+--------+--------------+ | 1 | Joe | 70000 | 1 | | 2 | Henry | 80000 | 2 | | 3 | Sam | 60000 | 2 | | 4 | Max | 90000 | 1 | +----+-------+--------+--------------+
The Department
table holds all departments of the company.
+----+----------+ | Id | Name | +----+----------+ | 1 | IT | | 2 | Sales | +----+----------+
Write a SQL query to find employees who have the highest salary in each of the departments. For the above tables, Max has the highest salary in the IT department and Henry has the highest salary in the Sales department.
+------------+----------+--------+ | Department | Employee | Salary | +------------+----------+--------+ | IT | Max | 90000 | | Sales | Henry | 80000 | +------------+----------+--------+
#way-1
select t.Name as Department, e.Name as Employee, t.Salary
from
Employee as e,
(
select d.Id, d.Name, max(m.salary) as Salary
from Department as d, Employee as m
where d.Id=m.DepartmentId group by m.DepartmentId
) as t
where
e.DepartmentId = t.Id and e.Salary = t.Salary;
#way-2
select
d.Name as Department, k.Name as Employee, k.Salary
from
Department d,
(select a.Name, a.Salary, a.DepartmentId
from Employee a
where (select count(Name) from Employee where DepartmentId = a.DepartmentId and Salary > a.Salary) = 0
) as k
where
d.Id = k.DepartmentId
Write a SQL query to deleteall duplicate email entries in a table named Person
, keeping only unique emails based on its smallest Id.
+----+------------------+ | Id | Email | +----+------------------+ | 1 | john@example.com | | 2 | bob@example.com | | 3 | john@example.com | +----+------------------+ Id is the primary key column for this table.
For example, after running your query, the above Person
table should have the following rows:
+----+------------------+ | Id | Email | +----+------------------+ | 1 | john@example.com | | 2 | bob@example.com | +----+------------------+
#way-1
#delete a from Person a,Person b where a.Email = b.Email and a.Id > b.Id;
#way-2
delete a from Person a inner join Person b on a.Email = b.Email and a.Id > b.Id;
197. Rising Temperature
Given a Weather
table, write a SQL query to find all dates' Ids with higher temperature compared to its previous (yesterday's) dates.
+---------+------------+------------------+ | Id(INT) | Date(DATE) | Temperature(INT) | +---------+------------+------------------+ | 1 | 2015-01-01 | 10 | | 2 | 2015-01-02 | 25 | | 3 | 2015-01-03 | 20 | | 4 | 2015-01-04 | 30 | +---------+------------+------------------+For example, return the following Ids for the above Weather table:
+----+ | Id | +----+ | 2 | | 4 | +----+
#way-1
#select a.ID from Weather a inner join Weather b on TO_DAYS(a.Date) = TO_DAYS(b.Date) + 1 and a.Temperature > b.Temperature;
#way-2
select a.ID from Weather a, Weather b where TO_DAYS(a.Date) = TO_DAYS(b.Date) + 1 and a.Temperature > b.Temperature;
The Trips
table holds all taxi trips. Each trip has a unique Id, while Client_Id and Driver_Id are both foreign keys to the Users_Id at the Users
table. Status is an ENUM type of (‘completed’, ‘cancelled_by_driver’, ‘cancelled_by_client’).
+----+-----------+-----------+---------+--------------------+----------+ | Id | Client_Id | Driver_Id | City_Id | Status |Request_at| +----+-----------+-----------+---------+--------------------+----------+ | 1 | 1 | 10 | 1 | completed |2013-10-01| | 2 | 2 | 11 | 1 | cancelled_by_driver|2013-10-01| | 3 | 3 | 12 | 6 | completed |2013-10-01| | 4 | 4 | 13 | 6 | cancelled_by_client|2013-10-01| | 5 | 1 | 10 | 1 | completed |2013-10-02| | 6 | 2 | 11 | 6 | completed |2013-10-02| | 7 | 3 | 12 | 6 | completed |2013-10-02| | 8 | 2 | 12 | 12 | completed |2013-10-03| | 9 | 3 | 10 | 12 | completed |2013-10-03| | 10 | 4 | 13 | 12 | cancelled_by_driver|2013-10-03| +----+-----------+-----------+---------+--------------------+----------+
The Users
table holds all users. Each user has an unique Users_Id, and Role is an ENUM type of (‘client’, ‘driver’, ‘partner’).
+----------+--------+--------+ | Users_Id | Banned | Role | +----------+--------+--------+ | 1 | No | client | | 2 | Yes | client | | 3 | No | client | | 4 | No | client | | 10 | No | driver | | 11 | No | driver | | 12 | No | driver | | 13 | No | driver | +----------+--------+--------+
Write a SQL query to find the cancellation rate of requests made by unbanned clients between Oct 1, 2013 and Oct 3, 2013. For the above tables, your SQL query should return the following rows with the cancellation rate being rounded to two decimal places.
+------------+-------------------+ | Day | Cancellation Rate | +------------+-------------------+ | 2013-10-01 | 0.33 | | 2013-10-02 | 0.00 | | 2013-10-03 | 0.50 | +------------+-------------------+
思路:首先在trip中找出日期区间内符合条件的记录,然后对于这些记录根据日期(request_at列)进行分组,找出每组符合status!='completed'条件的元组的个数作为分子,分组内记录个数总数作为分母,分子除以分母得出结果。
注意:
1、round(x,2)取小数点两位
2、order by ... asc 升序
3、sum() 求和
4、
case sex
when '1' then '男'
when '2' then '女'
else '其他'
end
select
request_at as Day,
round(sum(case Status when "completed" then 0 else 1 end)/count(*), 2) as 'Cancellation Rate'
from
(select *
from Trips
where
client_id not in
(select users_id
from Users
where banned = "yes" and role = "client")
and request_at >= "2013-10-01" and request_at <= "2013-10-03"
) as t
group by request_at order by request_at asc;
There is a table World
+-----------------+------------+------------+--------------+---------------+ | 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 | +-----------------+------------+------------+--------------+---------------+
A country is big if it has an area of bigger than 3 million square km or a population of more than 25 million.
Write a SQL solution to output big countries' name, population and area.
For example, according to the above table, we should output:
+--------------+-------------+--------------+ | name | population | area | +--------------+-------------+--------------+ | Afghanistan | 25500100 | 652230 | | Algeria | 37100000 | 2381741 | +--------------+-------------+--------------+
select w.name,w.population,w.area
from World w
where w.area > 3000000 or w.population>25000000;
596. Classes More Than 5 Students
There is a table courses
with columns: student and class
Please list out all classes which have more than or equal to 5 students.
For example, the table:
+---------+------------+ | student | class | +---------+------------+ | A | Math | | B | English | | C | Math | | D | Biology | | E | Math | | F | Computer | | G | Math | | H | Math | | I | Math | +---------+------------+
Should output:
+---------+ | class | +---------+ | Math | +---------+
Note:
The students should not be counted duplicate in each course.
create table temp (select * from courses group by student,class having count(*)>1);
#--删除重复数据
delete from courses where (student,class) in (select * from temp);
#--插入去重数据
insert into courses select * from temp;
#--删除临时表
drop table temp;
select c.class
from
(select class, count(*) as number from courses group by class) as c
where c.number >= 5;
select c.class
from courses c
group by c.class
having count(DISTINCT c.student)>4
X city built a new stadium, each day many people visit it and the stats are saved as these columns: id, date, people
Please write a query to display the records which have 3 or more consecutive rows and the amount of people more than 100(inclusive).
For example, the tablestadium
:
+------+------------+-----------+ | id | 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 | +------+------------+-----------+
For the sample data above, the output is:
+------+------------+-----------+ | id | date | people | +------+------------+-----------+ | 5 | 2017-01-05 | 145 | | 6 | 2017-01-06 | 1455 | | 7 | 2017-01-07 | 199 | | 8 | 2017-01-08 | 188 | +------+------------+-----------+
Note:
Each day only have one row record, and the dates are increasing with id increasing.
select
s.id, s.date, s.people
from
stadium s
where
(s.people>=100 and (select people from stadium where id=(s.id+1))>=100 and (select people from stadium where id=(s.id+2))>=100) or
(s.people>=100 and (select people from stadium where id=(s.id-1))>=100 and (select people from stadium where id=(s.id-2))>=100)
or
(s.people>=100 and (select people from stadium where id=(s.id-1))>=100 and (select people from stadium where id=(s.id+1))>=100) ;
X city opened a new cinema, many people would like to go to this cinema. The cinema also gives out a poster indicating the movies’ ratings and descriptions.
Please write a SQL query to output movies with an odd numbered ID and a description that is not 'boring'. Order the result by rating.
For example, table cinema
:
+---------+-----------+--------------+-----------+ | 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 | +---------+-----------+--------------+-----------+For the example above, the output should be:
+---------+-----------+--------------+-----------+ | id | movie | description | rating | +---------+-----------+--------------+-----------+ | 5 | House card| Interesting| 9.1 | | 1 | War | great 3D | 8.9 | +---------+-----------+--------------+-----------+
select *
from cinema
where id % 2 = 1 and description != 'boring'
order by rating desc;
Mary is a teacher in a middle school and she has a table seat
storing students' names and their corresponding seat ids.
+---------+---------+ | id | student | +---------+---------+ | 1 | Abbot | | 2 | Doris | | 3 | Emerson | | 4 | Green | | 5 | Jeames | +---------+---------+For the sample input, the output is:
+---------+---------+ | id | student | +---------+---------+ | 1 | Doris | | 2 | Abbot | | 3 | Green | | 4 | Emerson | | 5 | Jeames | +---------+---------+
Note:
If the number of students is odd, there is no need to change the last one's seat.
select
(case
when id % 2 = 1 and id = (select max(id) from seat) then id
when id % 2 = 1 then id + 1
else id - 1
end
) as id , student
from seat order by id;
627. Swap Salary
Given a table salary
, such as the one below, that has m=male and f=female values. Swap all f and m values (i.e., change all f values to m and vice versa) with a single update query and no intermediate temp table.
| id | name | sex | salary | |----|------|-----|--------| | 1 | A | m | 2500 | | 2 | B | f | 1500 | | 3 | C | m | 5500 | | 4 | D | f | 500 |After running your query, the above salary table should have the following rows:
| id | name | sex | salary | |----|------|-----|--------| | 1 | A | f | 2500 | | 2 | B | m | 1500 | | 3 | C | f | 5500 | | 4 | D | m | 500 |
update salary set sex =
(
case sex
when 'f' then 'm'
when 'm' then 'f'
end
);
FirstName, LastName, City, State