首页 > 试题广场 >

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

[编程题]给出employees表中排名为奇数行的first_name
  • 热度指数:186424 时间限制: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 a.first_name
from employees a
where (select count(*) from employees b where a.first_name<=b.first_name)%2=1;
看他所在的位置序号是否为奇数
发表于 2019-02-26 21:17:28 回复(1)
更多回答
关键点:

1. 用一个子查询来计算,有多少的b.first_name是比当前a.first_name少的,这个数就是行数(所以原表是默认按first_name来排序的?)

疑惑点:count中除了emp_no字段外都能通过,是因为主键的缘故么?另外b.*也不可以
select a.first_name
from employees a
where (select count(*) from employees b
      where a.first_name >= b.first_name) % 2 = 1
发表于 2019-06-17 17:30:28 回复(0)
select e1.first_name from employees e1 
where (select count(*) from employees e2 where e2.first_name <= e1.first_name) %2 = 1
发表于 2018-03-20 10:19:00 回复(0)
原题为:在first_name已经进行升序排列的表中找到并输出奇数行的数据;
先select查找到每一行的行数,因为已经进行升序了,所以可以通过对两个employees表的first_name进行遍历<=比较;
然后判断获得的行数是否为奇数即可
SELECT c.name, COUNT(fc.film_id) FROM
 (select category_id, COUNT(film_id) AS category_num FROM
     film_category  GROUP BY category_id HAVING count(film_id)>=5) AS cc,
 film AS f, film_category AS fc, category AS c
WHERE  f.description LIKE'%robot%'
AND f.film_id = fc.film_id
AND c.category_id = fc.category_id
AND c.category_id=cc.category_id
发表于 2017-09-05 15:24:21 回复(0)
考点:排序
题目:应该理解为先排序获取他的排名,然后按排序前的顺序进行他的排名奇偶判断。头好晕
照抄答案😅
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)
select first_name from employees e1 where 
(select count(1) from employees e2 where e2.first_name <= e1.first_name) % 2=1

这题最重要就是找到排序号的序列号,通过将两个表进行对比,可以达到排序的效果,把count(*)改为count(1)似乎可以减少查询时间
发表于 2020-06-15 23:17:42 回复(0)
mysql中这样写,结果与题目是一致的,但不知为何无法通过。
select first_name from 
(select e1.emp_no, e1.first_name, 
count(e1.first_name) as id1
from employees as e1, employees as e2
where e1.first_name <= e2.first_name
group by e1.first_name) as t
where id1 % 2 = 1
order by emp_no;

发表于 2020-05-18 10:01:08 回复(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)
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)
没注意题目中要求“输出的结果不需排序”……
原先写的
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)

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)
思路:先排出号码    然后再去奇数
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)
请问下大家,为什么用如下代码的窗口函数本地可以通过。
牛客网上提交却显示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 回复(21)
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,
            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 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 回复(1)
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)
我觉得题意就是按照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)