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

2024-04-18 09:52

本文主要是介绍SQL255 给出employees表中排名为奇数行的first_name,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目来源:

给出employees表中排名为奇数行的first_name_牛客题霸_牛客网

描述

对于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。

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');

解决 

解决方案一:

        先用row_number()对first_name排序,再利用mod()函数取出奇数行,这样取出的行里面的first_name就是我们要的了,由于要返回的是初始的排序状态,所以我们再套一层select直接从employees表取first_name,只要这里的first_name在我们上面取出的first_name里面就好了:

select e.first_name from employees e
where e.first_name in
(select a.first_name as first_name from
(select first_name,ROW_NUMBER() over(order by first_name) as rk
from employees) a
where mod(a.rk,2)!=0);
解决方案二:
mysql> select m1.first_name from-> (select e1.first_name,count(*) as 'rowid' from-> employees e1-> left join employees e2-> on e1.first_name >= e2.first_name-> group by e1.first_name ) as m1-> where m1.rowid % 2 = 1;
+------------+
| first_name |
+------------+
| Georgi     |
| Anneke     |
+------------+
2 rows in set (0.01 sec)

以下是我解题过程: 

        在我的查询中,我使用了 JOIN 条件 e1.first_name >= e2.first_name,这意味着查询返回的结果中,e1 表中的每一行都会与 e2 表中所有满足条件的行进行连接,找出小于等于他名字的计数。连接的结果不再按照原表的顺序排列,而是根据连接条件的满足程度和其他优化因素来确定最终的顺序。 (这是gpt说的)

mysql> select e1.first_name,count(*) from-> employees e1-> join employees e2-> on e1.first_name >= e2.first_name-> group by e1.first_name;
+------------+----------+
| first_name | count(*) |
+------------+----------+
| Kyoichi    |        4 |
| Georgi     |        3 |
| Bezalel    |        2 |
| Anneke     |        1 |
+------------+----------+
4 rows in set (0.00 sec)mysql>
mysql> select e1.first_name,count(e1.first_name) from-> employees e1-> join employees e2-> on e1.first_name >= e2.first_name-> group by e1.first_name;
+------------+----------------------+
| first_name | count(e1.first_name) |
+------------+----------------------+
| Kyoichi    |                    4 |
| Georgi     |                    3 |
| Bezalel    |                    2 |
| Anneke     |                    1 |
+------------+----------------------+
4 rows in set (0.00 sec)

但是这样查出来的 数据改变了数据的顺序:

mysql> select first_name from employees; 
+------------+
| first_name |
+------------+
| Georgi     |
| Bezalel    |
| Kyoichi    |
| Anneke     |
+------------+
4 rows in set (0.00 sec)mysql> select e1.first_name from-> employees e1-> join employees e2-> on e1.first_name >= e2.first_name-> group by e1.first_name;
+------------+
| first_name |
+------------+
| Kyoichi    |
| Georgi     |
| Bezalel    |
| Anneke     |
+------------+
4 rows in set (0.00 sec)mysql> select e1.first_name from-> employees e1-> join employees e2-> on e1.first_name >= e2.first_name;
+------------+
| first_name |
+------------+
| Kyoichi    |
| Georgi     |
| Kyoichi    |
| Bezalel    |
| Georgi     |
| Kyoichi    |
| Anneke     |
| Kyoichi    |
| Bezalel    |
| Georgi     |
+------------+
10 rows in set (0.00 sec)

        为了不改变表中的数据顺序,所以我想到了左连接,把e1表当作主表,外连接的功能就是把主表中的数据全部查出来,副表中没有一条数据与之匹配上的,就用null字段代替,且分组函数自动忽略null值:

mysql> select e1.first_name from-> employees e1-> left join employees e2-> on e1.first_name >= e2.first_name;
+------------+
| first_name |
+------------+
| Georgi     |
| Georgi     |
| Georgi     |
| Bezalel    |
| Bezalel    |
| Kyoichi    |
| Kyoichi    |
| Kyoichi    |
| Kyoichi    |
| Anneke     |
+------------+
10 rows in set (0.00 sec)

mysql> select * from-> employees e1-> left join employees e2-> on e1.first_name >= e2.first_name;
+--------+------------+------------+-----------+--------+------------+--------+------------+------------+-----------+--------+------------+
| emp_no | birth_date | first_name | last_name | gender | hire_date  | emp_no | birth_date | first_name | last_name | gender | hire_date  |
+--------+------------+------------+-----------+--------+------------+--------+------------+------------+-----------+--------+------------+
|  10001 | 1953-09-02 | Georgi     | Facello   | M      | 1986-06-26 |  10006 | 1953-04-20 | Anneke     | Preusig   | F      | 1989-06-02 |
|  10001 | 1953-09-02 | Georgi     | Facello   | M      | 1986-06-26 |  10002 | 1964-06-02 | Bezalel    | Simmel    | F      | 1985-11-21 |
|  10001 | 1953-09-02 | Georgi     | Facello   | M      | 1986-06-26 |  10001 | 1953-09-02 | Georgi     | Facello   | M      | 1986-06-26 |
|  10002 | 1964-06-02 | Bezalel    | Simmel    | F      | 1985-11-21 |  10006 | 1953-04-20 | Anneke     | Preusig   | F      | 1989-06-02 |
|  10002 | 1964-06-02 | Bezalel    | Simmel    | F      | 1985-11-21 |  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 |
|  10005 | 1955-01-21 | Kyoichi    | Maliniak  | M      | 1989-09-12 |  10005 | 1955-01-21 | Kyoichi    | Maliniak  | M      | 1989-09-12 |
|  10005 | 1955-01-21 | Kyoichi    | Maliniak  | M      | 1989-09-12 |  10002 | 1964-06-02 | Bezalel    | Simmel    | F      | 1985-11-21 |
|  10005 | 1955-01-21 | Kyoichi    | Maliniak  | M      | 1989-09-12 |  10001 | 1953-09-02 | Georgi     | Facello   | M      | 1986-06-26 |
|  10006 | 1953-04-20 | Anneke     | Preusig   | F      | 1989-06-02 |  10006 | 1953-04-20 | Anneke     | Preusig   | F      | 1989-06-02 |
+--------+------------+------------+-----------+--------+------------+--------+------------+------------+-----------+--------+------------+
10 rows in set (0.00 sec)mysql> select * from-> employees e1-> left join employees e2-> on e1.first_name >  e2.first_name;
+--------+------------+------------+-----------+--------+------------+--------+------------+------------+-----------+--------+------------+
| emp_no | birth_date | first_name | last_name | gender | hire_date  | emp_no | birth_date | first_name | last_name | gender | hire_date  |
+--------+------------+------------+-----------+--------+------------+--------+------------+------------+-----------+--------+------------+
|  10001 | 1953-09-02 | Georgi     | Facello   | M      | 1986-06-26 |  10006 | 1953-04-20 | Anneke     | Preusig   | F      | 1989-06-02 |
|  10001 | 1953-09-02 | Georgi     | Facello   | M      | 1986-06-26 |  10002 | 1964-06-02 | Bezalel    | Simmel    | F      | 1985-11-21 |
|  10002 | 1964-06-02 | Bezalel    | Simmel    | F      | 1985-11-21 |  10006 | 1953-04-20 | Anneke     | Preusig   | F      | 1989-06-02 |
|  10005 | 1955-01-21 | Kyoichi    | Maliniak  | M      | 1989-09-12 |  10006 | 1953-04-20 | Anneke     | Preusig   | F      | 1989-06-02 |
|  10005 | 1955-01-21 | Kyoichi    | Maliniak  | M      | 1989-09-12 |  10002 | 1964-06-02 | Bezalel    | Simmel    | F      | 1985-11-21 |
|  10005 | 1955-01-21 | Kyoichi    | Maliniak  | M      | 1989-09-12 |  10001 | 1953-09-02 | Georgi     | Facello   | M      | 1986-06-26 |
|  10006 | 1953-04-20 | Anneke     | Preusig   | F      | 1989-06-02 |   NULL | NULL       | NULL       | NULL      | NULL   | NULL       |
+--------+------------+------------+-----------+--------+------------+--------+------------+------------+-----------+--------+------------+
7 rows in set (0.00 sec)

现在就跟这个顺序一样了: 

最终代码:

mysql> select m1.first_name from-> (select e1.first_name,count(*) as 'rowid' from-> employees e1-> left join employees e2-> on e1.first_name >= e2.first_name-> group by e1.first_name ) as m1-> where m1.rowid % 2 = 1;
+------------+
| first_name |
+------------+
| Georgi     |
| Anneke     |
+------------+
2 rows in set (0.01 sec)
改进的方案二:

方案一虽然能通过,其实并不完美,因为方案一没有问题的前提是employees 中的first_name没有重名的,如果我加了一条重名字的数据进去,就出问题了:

mysql> INSERT INTO employees VALUES(10007,'1953-09-02','Georgi','Facello','M','1986-06-26');
Query OK, 1 row affected (0.01 sec)

没执行insert操作前:

        如果你要像方案二一样通过join两张表来获得排名,那就必须去重, 要不然Georgi 为8,意味着小于等于他名字的有八个,这不就摇身一变,变成了名字最大的了吗

执行了insert操作后:

mysql> select e1.first_name,count(*) as 'rowid' from-> employees e1-> left join employees e2-> on e1.first_name >= e2.first_name-> group by e1.first_name ;
+------------+-------+
| first_name | rowid |
+------------+-------+
| Georgi     |     8 |
| Bezalel    |     2 |
| Kyoichi    |     5 |
| Anneke     |     1 |
+------------+-------+
4 rows in set (0.00 sec)

原因如下:

mysql> select * from-> employees e1-> left join employees e2-> on e1.first_name >=    e2.first_name;
+--------+------------+------------+-----------+--------+------------+--------+------------+------------+-----------+--------+------------+
| emp_no | birth_date | first_name | last_name | gender | hire_date  | emp_no | birth_date | first_name | last_name | gender | hire_date  |
+--------+------------+------------+-----------+--------+------------+--------+------------+------------+-----------+--------+------------+
|  10001 | 1953-09-02 | Georgi     | Facello   | M      | 1986-06-26 |  10007 | 1953-09-02 | Georgi     | Facello   | M      | 1986-06-26 |
|  10001 | 1953-09-02 | Georgi     | Facello   | M      | 1986-06-26 |  10006 | 1953-04-20 | Anneke     | Preusig   | F      | 1989-06-02 |
|  10001 | 1953-09-02 | Georgi     | Facello   | M      | 1986-06-26 |  10002 | 1964-06-02 | Bezalel    | Simmel    | F      | 1985-11-21 |
|  10001 | 1953-09-02 | Georgi     | Facello   | M      | 1986-06-26 |  10001 | 1953-09-02 | Georgi     | Facello   | M      | 1986-06-26 |
|  10002 | 1964-06-02 | Bezalel    | Simmel    | F      | 1985-11-21 |  10006 | 1953-04-20 | Anneke     | Preusig   | F      | 1989-06-02 |
|  10002 | 1964-06-02 | Bezalel    | Simmel    | F      | 1985-11-21 |  10002 | 1964-06-02 | Bezalel    | Simmel    | F      | 1985-11-21 |
|  10005 | 1955-01-21 | Kyoichi    | Maliniak  | M      | 1989-09-12 |  10007 | 1953-09-02 | Georgi     | Facello   | M      | 1986-06-26 |
|  10005 | 1955-01-21 | Kyoichi    | Maliniak  | M      | 1989-09-12 |  10006 | 1953-04-20 | Anneke     | Preusig   | F      | 1989-06-02 |
|  10005 | 1955-01-21 | Kyoichi    | Maliniak  | M      | 1989-09-12 |  10005 | 1955-01-21 | Kyoichi    | Maliniak  | M      | 1989-09-12 |
|  10005 | 1955-01-21 | Kyoichi    | Maliniak  | M      | 1989-09-12 |  10002 | 1964-06-02 | Bezalel    | Simmel    | F      | 1985-11-21 |
|  10005 | 1955-01-21 | Kyoichi    | Maliniak  | M      | 1989-09-12 |  10001 | 1953-09-02 | Georgi     | Facello   | M      | 1986-06-26 |
|  10006 | 1953-04-20 | Anneke     | Preusig   | F      | 1989-06-02 |  10006 | 1953-04-20 | Anneke     | Preusig   | F      | 1989-06-02 |
|  10007 | 1953-09-02 | Georgi     | Facello   | M      | 1986-06-26 |  10007 | 1953-09-02 | Georgi     | Facello   | M      | 1986-06-26 |
|  10007 | 1953-09-02 | Georgi     | Facello   | M      | 1986-06-26 |  10006 | 1953-04-20 | Anneke     | Preusig   | F      | 1989-06-02 |
|  10007 | 1953-09-02 | Georgi     | Facello   | M      | 1986-06-26 |  10002 | 1964-06-02 | Bezalel    | Simmel    | F      | 1985-11-21 |
|  10007 | 1953-09-02 | Georgi     | Facello   | M      | 1986-06-26 |  10001 | 1953-09-02 | Georgi     | Facello   | M      | 1986-06-26 |
+--------+------------+------------+-----------+--------+------------+--------+------------+------------+-----------+--------+------------+
16 rows in set (0.00 sec)mysql>
mysql> select e1.first_name from-> employees e1-> left join employees e2-> on e1.first_name >= e2.first_name;
+------------+
| first_name |
+------------+
| Georgi     |
| Georgi     |
| Georgi     |
| Georgi     |
| Bezalel    |
| Bezalel    |
| Kyoichi    |
| Kyoichi    |
| Kyoichi    |
| Kyoichi    |
| Kyoichi    |
| Anneke     |
| Georgi     |
| Georgi     |
| Georgi     |
| Georgi     |
+------------+
16 rows in set (0.00 sec)

我们需要联合两个字段去重:

mysql> select  distinct e1.first_name ,e2.first_name #distinct去掉重名的-> from employees e1-> left join employees e2-> on e1.first_name >= e2.first_name;
+------------+------------+
| first_name | first_name |
+------------+------------+
| Georgi     | Georgi     |
| Georgi     | Anneke     |
| Georgi     | Bezalel    |
| Bezalel    | Anneke     |
| Bezalel    | Bezalel    |
| Kyoichi    | Georgi     |
| Kyoichi    | Anneke     |
| Kyoichi    | Kyoichi    |
| Kyoichi    | Bezalel    |
| Anneke     | Anneke     |
+------------+------------+
10 rows in set (0.00 sec)
mysql> select count(*) as rowid,m1.first_name from-> (->-> select  distinct e1.first_name  , e2.first_name  as name-> from employees e1-> left join employees e2-> on e1.first_name >= e2.first_name-> ) as m1 group by m1.first_name;
+-------+------------+
| rowid | first_name |
+-------+------------+
|     3 | Georgi     |
|     2 | Bezalel    |
|     4 | Kyoichi    |
|     1 | Anneke     |
+-------+------------+
4 rows in set (0.01 sec)

最终答案:

mysql> select m2.first_name from-> (select count(*) as rowid,m1.first_name from-> (->-> select  distinct e1.first_name  , e2.first_name  as name-> from employees e1-> left join employees e2-> on e1.first_name >= e2.first_name-> ) as m1 group by m1.first_name)as m2 where m2.rowid % 2 = 1;
+------------+
| first_name |
+------------+
| Georgi     |
| Anneke     |
+------------+
2 rows in set (0.00 sec)

这篇关于SQL255 给出employees表中排名为奇数行的first_name的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/914451

相关文章

如何占领消费者科技心智?这家中国企业给出标准答案

品牌的价值是什么? 沃伦·巴菲特和查理·芒格曾提出过著名的“护城河”模型,将品牌作为一家公司构建护城河的基本要素之一。 按照巴菲特的说法:“你会试着去创建一个跟迪士尼竞争的品牌吗?可口可乐这个品牌让人联想到世界各地畅饮可口可乐的不同人。这就是你希望一家企业能够拥有的,这就是护城河。” 原因在于,品牌常常和消费者的忠诚度、企业的影响力、产品的定价能力挂钩。如果说技术、产品和渠道构成了一家企业的

Spark算子:RDDAction操作–first/count/reduce/collect/collectAsMap

first def first(): T first返回RDD中的第一个元素,不排序。 scala> var rdd1 = sc.makeRDD(Array(("A","1"),("B","2"),("C","3")),2)rdd1: org.apache.spark.rdd.RDD[(String, String)] = ParallelCollectionRDD[33] at mak

窗口函数之排名函数与分析函数

窗口函数中的排名函数与分析函数实在是太好用了,尤其是row_number和lead 全局表如下: 排名函数 1.row_number ROW_NUMBER() over (partition by name order by testid)       (partition by 是可选的)   其他排名函数相同  按照order排序  返回顺序

什么是FIFO管理单元?(First-In-First-Out)

FIFO(First-In-First-Out,先进先出)管理单元是一种广泛用于数据处理和存储系统中的机制,其核心理念是确保最早进入系统的数据最早被处理或移出。这种管理方法类似于排队的方式,最早进入队列的项目会最先得到服务。         FIFO管理单元通常用于缓冲区(Buffer)设计、任务调度、内存管理等多个领域。在硬件和软件系统中,FIFO机制有助于保证数据的有序处理,

AppML 案例:Employees

AppML 案例:Employees 介绍 AppML(Application Markup Language)是一种创新的Web开发技术,它允许开发人员使用标记语言来构建Web应用程序。在本文中,我们将探讨一个使用AppML构建的员工管理系统的案例。这个案例将展示AppML如何简化数据绑定、事件处理和用户界面设计。 系统需求 员工管理系统旨在帮助公司有效地管理其员工信息。系统的主要功能包

腾讯面试题:根据上排给出的十个数,在其下排填出对应的十个数。

版权所有。所有权利保留。 欢迎转载,转载时请注明出处: http://blog.csdn.net/xiaofei_it/article/details/17172769 根据上排给出的十个数,在其下排填出对应的十个数,要求下排每个数都是先前上排那十个数在下排出现的次数。 上排的十个数如下: 0,1,2,3,4,5,6,7,8,9

.对于一个栈,给出输入项 A,B,C,D,如果输入项序列为 A,B,C,D,试给出全部可能的输出序列

要找到栈的所有可能输出序列,我们需要考虑栈的特性,即“后进先出”(LIFO)。我们可以通过不同的入栈和出栈顺序来生成所有可能的输出序列。 假设输入项序列是 A, B, C, D。我们通过模拟入栈和出栈过程,递归地生成所有可能的输出序列。 下面是一个详细的递归算法,用于生成所有可能的输出序列: 定义递归函数:该函数处理当前栈状态、剩余未处理的输入项以及已生成的输出序列。递归终止条件:当所有输入

更改物料说明后,在MTL_SYSTEM_ITEMS_B表中无变化

更改物料说明后,在MTL_SYSTEM_ITEMS_B表中无变化 我在中文环境中更改物料说明,查看MTL_SYSTEM_ITEMS_B表时发现,物料说明并没有变化;但查询MTL_SYSTEM_ITEMS_TL表时发现,物料说明已更改为新值。这样就造成了“同一物料的描述不同”。 通过查询Oracle eTRM得到如下信息: Items now support multiling

在单链表和双链表中删除倒数第k个节点

实现的完整代码如下: //在单链表和双链表中删除倒数第k个节点public class DeleteList{//单链表节点的定义public static class Node{int value;Node next;public Node(int data){this.value=data;}}//删除单链表中倒数第k个节点public static int DeletList_K(

在单链表中删除指定值的节点

import java.util.*;//在单链表中删除指定值的节点public class delNode{//节点的定义public static class Node{int value;Node next;public Node(int data){this.value=data;}}//一、变量法存储public static Node DelNode(Node head,in