首页 > 试题广场 >

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

[编程题]给出employees表中排名为奇数行的first_name
  • 热度指数:205607 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
对于employees表中,输出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`)
);
输入:
emp_no birth_date first_name last_name gender hire_date
10001 1953-09-02 Georgi Facello M 1986-06-26
10002 1964-06-02 Bezalel Simmel F 1985-11-21
10005
1955-01-21 Kyoichi Maliniak M 1989-09-12
10006 1953-04-20 Anneke Preusig F 1989-06-02
输出:
Georgi
Anneke
如对以上示例数据的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 T.first_name 
from (
    select T2.first_name,(
        select count(*) 
        from employees T3
        where T3.first_name <= T2.first_name
    ) row_id
    from employees T2
) T
where row_id%2 = 1


发表于 2021-03-27 18:00:17 回复(0)
首先题目的叙述有问题,导致理解有误,输出的数据与参考答案不同。先给出正确的题目叙述:对于employees表,在对first_name进行排名后,选出奇数排名对应的first_name
1、本题用到了三层 SELECT 查询,为了便于理解,采用缩进方式分层,且最外层对应e1,最内层对应e3;
2、在e3层中,采用 COUNT() 函数对 e2.first_name 进行排名标号,即在给定 e2.first_name的情况下,不大于 e2.first_name 的 e3.first_name 的个数有多少,该个数刚好与 e2.first_name 的排名标号匹配,且将该值命名为 rowid;
/*注意:排名标号后并未排序,即[Bob, Carter, Amy]的排名是[2,3,1],选取奇数排名后输出[Carter, Amy],所以可见参考答案中的first_name并未按字母大小排序*/
3、在e1层中,直接在限定条件 e1.rowid % 2 = 1 下,代表奇数行的 rowid,选取对应的 e1.first_name;
4、e2层则相当于连接e1层(选取表示层)与e3层(标号层)的桥梁。
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 % 2 = 1

编辑于 2017-09-11 10:36:15 回复(47)

感觉这样简单多!

SELECT e1.first_name FROM
employees e1
WHERE 
(SELECT count(*) FROM employees e2 
WHERE e1.first_name <=e2.first_name)%2=1;
发表于 2017-12-11 11:11:04 回复(46)
没注意题目中要求“输出的结果不需排序”……
原先写的
SELECT
    t.first_name
FROM
(
    SELECT 
        first_name
        , ROW_NUMBER() OVER(ORDER BY first_name ASC) AS  r_num
    FROM employees
) AS t 
WHERE t.r_num % 2 = 1;
怎么也运行不成功。
SELECT
    e.first_name
FROM employees e JOIN
(
    SELECT 
        first_name
        , ROW_NUMBER() OVER(ORDER BY first_name ASC) AS  r_num
    FROM employees
) AS t 
ON e.first_name = t.first_name
WHERE t.r_num % 2 = 1;
运行成功


发表于 2020-09-07 23:19:28 回复(35)
SQL来自他人的答案,因为一开始没看明白题目(可能看明白了一下子也没思路)。

SQL说明:
1. 首先题目要求对first_name排序,所以子查询里有first_name的比较。
2. 通过比较,如果 e1.first_name 是第一位,那 e2.first_name 只有1个,就是 e1.first_name 本身,1%2=1;如果 e1.first_name 排在第二位,就有它和比它小的2个 e2.first_name,2%2=0,所以不选,以此类推。

select e1.first_name
  from employees e1
where (select count(*) from employees e2 where e1.first_name >= e2.first_name)%2=1
;
发表于 2018-10-07 10:22:22 回复(10)
思路:先排出号码    然后再去奇数
1.利用count函数 排号  
SELECT COUNT(*) FROM employees E2 WHERE E1.first_name>=E2.first_name
2.然后取奇数

SELECT E1.first_name FROM employees E1

WHERE (SELECT COUNT(*) FROM employees E2 WHERE E1.first_name>=E2.first_name)%2=1;

发表于 2018-05-15 15:21:40 回复(0)

SELECT E1.first_name FROM employees E1

WHERE (SELECT COUNT(*) FROM employees E2 WHERE E1.first_name>=E2.first_name)%2=1;

发表于 2017-08-10 13:57:12 回复(9)
请问下大家,为什么用如下代码的窗口函数本地可以通过。
牛客网上提交却显示0%通过,这是什么原因呢? 如何修改下列代码使其通过?
select tt.first_name
from
(select first_name,
row_number() over (order by first_name) as row_idx
from employees) as tt
where tt.row_idx%2=1;


编辑于 2020-09-01 16:53:26 回复(23)
SELECT e1.first_name FROM
employees e1
WHERE 
(SELECT count(*) FROM employees e2 
WHERE e1.first_name >=e2.first_name)%2=1;
看了好多讨论,困惑点主要下面几个,按个人理解回答下:
1)为什么是>= 不是<=
回答:因为题中说“first_name升序排序”,如果是降序就是<=。
2)为什么没有order by
回答:因为题中说了“输出时不用排序”,输出顺序应按原表顺序。
3)为什么不能用row_number()
回答:因为row_number()会默认更改first_name排序。
发表于 2020-08-18 23:07:47 回复(0)
select first_name from  ( 
    select e2.first_name,( select count(*) from employees as e1 where e1.first_name <= e2.first_name )  as rownum 
    from employees as e2 
    where rownum % 2 =1 
)

计算行号的方法 : 有多少个小于等于e2.first_name的记录的个数就是e2.first_name的行号

编辑于 2017-08-31 22:36:05 回复(3)
这个题的过程是,原表排序后变为新表,取出新表中排奇数位的行,输出时这些行的排列顺序还要跟他们在原表时的排列顺序一样。
第一种是错误做法:
select first_name
from
(select first_name,row_number() over(order by first_name) as num
from employees) as a
where num % 2=1
这样输出的结果只会与新表的排列顺序一样,不会与未排序前的顺序一样。
所以选取结果时必须是从原表中选取。
select first_name from employees where first_name in
(select first_name
from
(select first_name,row_number() over(order by first_name) as num
from employees) as a
where num % 2=1)



发表于 2022-01-18 15:17:10 回复(2)
SELECT 
    first_name
FROM 
    (SELECT first_name,
            emp_no,
            row_number() over(ORDER BY first_name ASC) AS r
     FROM employees
     ORDER BY emp_no) AS t
WHERE t.r % 2 = 1
一开始用窗口函数怎么也弄不出来结果,后来发现题目要求不排序,所以默认的是以原来的emp_no为顺序进行输出
所以在用窗口函数后,再将emp_no按照原顺序进行排列即可

发表于 2021-10-06 17:23:47 回复(2)
对于题目, 我的理解是,不打乱插入顺序的情况下,输出:按first_name排升序后,取奇数行的first_name。看了别的帖子,我半天没明白题目的意思,这描述得,emmmm....?

我们来看下面这两个表,按例子,first_name在表中的顺序是下面这样子的
  e1表         e2表
+------------+  +------------+
| first_name|  | first_name|
+------------+  +------------+
| Georgi  |  | Georgi  |
| Bezalel  |  | Bezalel  |
| Kyoichi  |  | Kyoichi  |
| Anneke   |  | Anneke  |
+------------+  +------------+ 
输出的是Georgi、Anneke,降序,但题目要求是按first_name升序后取值, 那说明输出结果不需要排序。
来, 我们来分析一下,
  1.   e1.Georgi >= e2.first_name 的值有多少个,3个,对吧
  2.   e1.Bezalel >= e2.first_name 的值有多少个,2个,对吧
  3.   e1.Kyoichi >= e2.first_name 的值有多少个,4个,对吧
  4.   e1.Anneke >= e2.first_name 的值有多少个,1个,对吧
  5. 假如我们对first_name升序排序,是不是刚好和前面几个值一一对应?
  6. +----------------------------------------+
    |  1    |    2    |  3  | 4     |
    +----------------------------------------+ 
    | Anneke | Bezalel | Georgi | Kyoichi|
    +----------------------------------------+ 
    
    那么,很明显了,e1.first_name >= e2.first_name的count(1) 就是first_name升序排序的顺序编号,到这里,我们只需要对顺序编号对2取余数等于1就可以了
SELECT e1.first_name FROM employees as e1 WHERE (
	SELECT COUNT(1) FROM employees as e2 WHERE e1.first_name >= e2.first_name 
) % 2 = 1;


发表于 2020-06-29 16:14:23 回复(0)
select o.first_name 
from (SELECT @rowno:=@rowno + 1 AS rowno, e.first_name FROM employees e,(SELECT @rowno:=0)) o
where o.rowno % 2 = 1;
编辑于 2018-05-27 15:20:09 回复(2)
题目都没写完吧?   答案跟题目都不一致  搞笑
发表于 2017-07-17 17:06:09 回复(0)
select first_name 
from 
(select emp_no, first_name ,
ROW_NUMBER() OVER (ORDER BY first_name ASC) AS t1 from employees ) t2
where t1 % 2 = 1
order by t2.emp_no
不懂为啥A / G 顺序反了。就加了个order by no
发表于 2021-02-18 21:58:05 回复(1)
我觉得题意就是按照first_name先排序,然后再取出奇数行的数据,通过代码验证可以输出题目中给出的输出形式,但是不能通过。。
select first_name 
from (select first_name, row_number() over (order by first_name) as rank from employees order by rank) 
where rank %2 = 1;

发表于 2020-04-04 14:55:35 回复(12)
-- 先要对表排序,然后找到每一行在表中的位置
-- 找到奇数位置的行,需要涉及到对同一个表的重复使用
select e1.first_name
from employees as e1
where (
select count(*) 
from employees as e2
where e2.first_name <= e1.first_name    -- 统计当前(e1)first_name之前有多少条数据,即排在多少行数据
)%2=1;

发表于 2019-09-16 23:36:44 回复(3)
代码
select e1.first_name as first_name 
from employees as e1
where (select count(*) 
            from employees as e2 
            where e1.first_name >= e2.first_name) % 2 = 1
结果
Anneke
Saniya
Georgi
数据库数据
查出来的结果是自动按first_name排序后的奇数行结果,但这样符合题目的要求吗?已AC代码
求大神解惑!
发表于 2018-09-03 16:11:25 回复(2)
SELECT e1.first_name from employees e1, employees e2 
where e1.first_name>=e2.first_name
group by e1.first_name
HAVING  COUNT(e1.first_name)%2=1
ORDER BY e1.first_name DESC

不能通过,不知道为什么
发表于 2020-09-24 15:01:06 回复(3)
  • 二维码

    扫描二维码,关注牛客网

  • 二维码

    下载牛客APP,随时随地刷题