首页 > 试题广场 >

给出employees表中排名为奇数行的first_name

[编程题]给出employees表中排名为奇数行的first_name
  • 热度指数:186850 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
对于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');
输出格式:
first
Georgi
Anneke
请你在不打乱原序列顺序的情况下,输出:按first_name排升序后,取奇数行的first_name
如对以上示例数据的first_name排序后的序列为:Anneke、Bezalel、Georgi、Kyoichi。
则原序列中的Georgi排名为3,Anneke排名为1,所以按原序列顺序输出Georgi、Anneke

示例1

输入

drop table if exists  `employees` ; 
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
Anneke
SELECT 
    first_name AS first
FROM (
    SELECT 
        first_name,
        ROW_NUMBER()OVER(ORDER BY first_name) AS row_first_name
    FROM employees
    GROUP BY first_name
) AS order_first_name
JOIN employees e USING(first_name)
WHERE MOD(row_first_name, 2) <> 0;

OR:

SELECT 
    first_name AS first
FROM (
    SELECT 
        first_name,
        ROW_NUMBER()OVER(ORDER BY first_name) AS row_first_name
    FROM employees
    GROUP BY first_name
) AS order_first_name
JOIN employees e USING(first_name)
WHERE row_first_name %2 <> 0;

发表于 2024-04-07 21:14:32 回复(0)
这个题目比较关键的是,只要在 SQL 中使用过 ORDER BY 字段(包括在 开窗函数 OVER 中),都会导致最后返回的结果的顺序发生改变,因此如果想要结果顺序不变,则应该在子查询中按照 emp_no 排序,以此保证依然是原始的顺序
```
SELECT
    first
FROM
    (
        SELECT
            first_name first,
            row_number() OVER (
                ORDER BY
                    first_name
            ) t_rank
        FROM
            employees
        ORDER BY
            emp_no
    ) m
WHERE 
    m.t_rank %2=1

```
编辑于 2024-02-29 11:43:02 回复(0)
select t.first_name 
from employees,
(select first_name,row_number() over(order by first_name) as rn from employees) as t
where t.rn%2=1
and employees.first_name=t.first_name
order by emp_no;
题目说不打乱原序列顺序,意思就是按emp_no进行排序(流汗黄豆,跟我搞阅读理解呢)
编辑于 2024-01-14 17:25:07 回复(0)
select e1.first_name from  employees e1 LEFT join employees e2 on e1.first_name>=e2.first_name
group by e1.first_name
having count(e2.first_name)%2=1

 直接join不行,得是 left join 才行,不懂—_—
发表于 2023-11-20 10:45:38 回复(0)
# 先将数据原来顺序进行排名,以及按照first_name升序进行排名得到
with t1 as (
    select first_name, ROW_NUMBER() OVER() as t_rank1, ROW_NUMBER() OVER (ORDER BY first_name) as t_rank2
    from employees
)
# 想要排名为奇数
select first_name as first
from t1
where MOD(t_rank2, 2) != 0
order by t_rank1;

发表于 2023-10-27 00:15:15 回复(1)
# 只用窗口函数就行
select
   first_name as first
from
(
    select
        first_name,
        row_number() over () rk1 ,
        row_number() over (order by first_name) rk2
    from employees
)t1
where rk2 % 2 = 1
order by rk1
;
发表于 2023-10-03 17:26:02 回复(0)
select
    t4.first_name
from
    (select
        first_name,
        sum(1) over (rows between unbounded preceding and current row) rank1
    from
        (select first_name from employees t1 order by t1.first_name ) t1) t3,
    (select
        t2.first_name,
        (sum(1) over (rows between unbounded preceding and current row)) rank2
    from
        employees t2) t4
where
    t3.first_name = t4.first_name
    and rank1 % 2 = 1
order by
    rank2 asc

发表于 2023-09-15 20:34:21 回复(0)
# 对于employees表中,输出first_name排名(按first_name升序排序)为奇数的first_name
# 注意:按照原来顺序输出

with dwd_data as (
select 
emp_no,
first_name,
row_number()over(order by first_name ) rn
from employees 
)

select first_name from (
select
emp_no,
first_name
from dwd_data 
where rn%2=1
order by 1
) tt
;


发表于 2023-09-12 20:20:23 回复(0)
select employees.first_name from employees left join (select first_name, row_number() over(order by first_name) as ranking from employees)A on employees.first_name=A.first_name where ranking%2=1; 
发表于 2023-06-26 15:42:20 回复(0)
大佬们的解释我甚至看不太懂...
用了最笨的办法:
1.先使用窗口函数排序--成立表1
SELECT first_name,
               ROW_NUMBER () OVER (ORDER BY first_name ASC) AS rk
FROM employees

2.从表1中取单数序号的数据--成立表2
SELECT first_name
FROM (SELECT first_name,
            ROW_NUMBER () OVER (ORDER BY first_name ASC) AS rk
            FROM employees
            ) AS a
WHERE rk % 2 = 1

3.再从原表:employees取出的数据比表2中有的数据
SELECT first_name AS first
FROM employees
WHERE first_name in
(
SELECT first_name
FROM (SELECT first_name,
      ROW_NUMBER () OVER (ORDER BY first_name ASC) AS rk
      FROM employees) AS a
WHERE rk % 2 = 1
)

发表于 2023-06-03 19:40:58 回复(3)
select
    t1.first_name
from
    employees t1
    inner join (
        select
            first_name,
            row_number() over (
                order by
                    first_name asc
            ) ranking
        from
            employees
    ) t2 on t1.first_name = t2.first_name
    and mod(t2.ranking, 2) = 1

发表于 2023-05-22 11:41:59 回复(0)
窗口函数 、%2
select tmp.first_name
from(select
    emp_no,
    first_name,
    row_number() over(order by first_name  ) as num
from
    employees) as tmp
where(tmp.num%2=1)
order by emp_no

发表于 2023-05-15 14:07:48 回复(0)
根据题目,可简化有以下几个需求:①对first_name列进行排序②筛选出排序后序列号为奇数的fist_name③再根据emp_no按照原表的顺序排列。利用窗口函数顺利执行:
select first_name as first from
(select first_name,rank()over(order by first_name) as posn
from employees
order by emp_no) as a
where posn % 2 =1
因为窗口函数执行顺序在order by之后。先对emp_no排序,即保证输出为原表顺序;
再通过
rank()over(order by first_name)
在此基础上添加以first_name排序的序号posn列。
以上面语句为新表,检索条件为奇数的序号列的fist_name即可
发表于 2023-05-05 18:42:39 回复(0)
select first_name
from employees
where first_name in

(select first_name
from

(select first_name, row_number() over(order by first_name asc) as rn
from employees
order by first_name asc) as t

where rn % 2 = 1)

发表于 2023-04-18 23:19:33 回复(0)
select first_name
from(select a.first_name, count(*)as rownum 
	from employees a
	join employees b
	on a.first_name>=b.first_name
	group by a.first_name)as c
	where rownum %2 =1


发表于 2023-01-29 15:58:48 回复(0)
#题目的意思应该是,最后输出的名字的顺序和原来的employees中的顺序是一样的
#纯粹想熟悉窗口函数,才用窗口函数解这道题
select first
from (
    select first_name as first,
    row_number() over(order by emp_no) as rn,
    row_number() over(order by first_name) as rk
    from employees
    order by rk desc
)t 
where t.rk%2!=0
order by t.rn;

发表于 2022-12-24 14:20:51 回复(0)
select first_name first from 
(select emp_no, first_name,row_number()over(order by first_name)rk from employees)e
where rk%2!=0 order by emp_no      

emp_no跟原表顺序一致

发表于 2022-11-29 17:09:03 回复(0)
select e.first_name from employees e inner join (
    select first_name,rank() over(order by first_name) as rank_no
    from employees
)t 
on e.first_name = t.first_name
where (t.rank_no % 2)!=0;
使用窗口函数和内连接

发表于 2022-11-15 19:48:54 回复(0)
select first_name first
from employees
where first_name in (
    select first_name
    from (
        select *,row_number() over(order by first_name) rk
        from employees) a
where rk%2<>0
)

发表于 2022-11-11 10:50:18 回复(0)