SQL练习:SQL61_较难
题目: 对于employees表中,输出first_name排名(按first_name升序排序)为奇数的first_name
CREATE TABLE `employees` (
`emp_no` int(11) NOT NULL,
`birth_date` date NOT NULL,
`first_name` varchar(14) NOT NULL,
`last_name` varchar(16) NOT NULL,
`gender` char(1) NOT NULL,
`hire_date` date NOT NULL,
PRIMARY KEY (`emp_no`));
INSERT INTO employees VALUES(10001,'1953-09-02','Georgi','Facello','M','1986-06-26');
INSERT INTO employees VALUES(10002,'1964-06-02','Bezalel','Simmel','F','1985-11-21');
INSERT INTO employees VALUES(10005,'1955-01-21','Kyoichi','Maliniak','M','1989-09-12');
INSERT INTO employees VALUES(10006,'1953-04-20','Anneke','Preusig','F','1989-06-02');
输出格式:
因为Georgi按first_name排名为3,Anneke按first_name排名为1,所以会输出这2个,且输出时不需排序。
first_name |
---|
Georgi |
Anneke |
题解:
# 方式1:WHERE+子查询+COUNT
SELECT A.first_name
FROM employees A
WHERE (
SELECT COUNT(*) # COUNT为奇数,则此first_name排序为奇
FROM employees B
WHERE A.first_name >= B.first_name) & 1 # 计算所在字段B.first_name的排序(>=的字段数)
# 方式2:FROM+双重子查询+COUNT
SELECT e1.first_name
FROM (SELECT e2.first_name,(SELECT COUNT(*)
FROM employees AS e3
WHERE e3.first_name <= e2.first_name) AS rowid
FROM employees AS e2) AS e1
WHERE e1.rowid & 1
# 方式3:FROM+子查询+ROW_NUMBER
SELECT A.first_name
FROM employees A,(SELECT first_name, ROW_NUMBER() OVER(ORDER BY first_name) AS r_num
FROM employees) AS B
WHERE B.r_num & 1 AND A.first_name = B.first_name
## 求奇数:按位与【& 1】,或求余【% 2 = 1】。不过当然位运算比较快啦。
## 求排序:聚合函数COUNT,或窗口函数ROW_NUMBER
- 个人整理的笔记,仅供学习使用,有问题麻烦指正。
- 题目来源于:牛客网