首页 > 解决方案 > Codesignal.com 闹钟解决方案

问题描述

您正在开发一个闹钟应用程序,其工作方式如下:用户可以设置日期和时间,该应用程序将从给定日期开始每周在给定时间响铃,直到今年年底。

开始日期是以下结构的 userInput 表中的唯一记录:

input_date:第一个闹钟的日期和时间(DATETIME 类型)。给定表格,您的任务是用单列alarm_date 组成结果表格。此列应包含闹钟按升序响起的所有日期(包括时间)。

输入输出 1输入输出2

 CREATE PROCEDURE alarmClocks()
 BEGIN
 select @a alarm_date
    from userInput, 
         (select 1 union select 2 union select 3 union select 4) x,
         (select 1 union select 2 union select 3 union select 4) y,
         (select 1 union select 2 union select 3 union select 4) z
    where year(ifnull(@a:=date_add(@a, interval 1 week), @a:=input_date)) 
        = year(input_date);
 END

我不明白这种语法

(select 1 union select 2 union select 3 union select 4) x

谁能给我解释一下?

标签: mysqlsqlselectunion

解决方案


UNIONSELECT通过将第二个操作数“从上到下”附加到第一个操作数来组合两个关系(例如 a 的结果集)。

在您的示例SELECT 1中可能如下所示:

+---+
| 1 |
+===+
| 1 |
+---+

并且SELECT 2

+---+
| 2 |
+===+
| 2 |
+---+

SELECT 1 UNION SELECT 2将导致:

+---+
| 1 |
+===+
| 1 |
+---+
| 2 |
+---+

对于其他查询,依此类推。您的整体SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4将导致:

+---+
| 1 |
+===+
| 1 |
+---+
| 2 |
+---+
| 3 |
+---+
| 4 |
+---+

UNION也消除了重复。这SELECT 1 UNION SELECT 1将导致:

+---+
| 1 |
+===+
| 1 |
+---+

不会导致:

+---+
| 1 |
+===+
| 1 |
+---+
| 1 |
+---+

如果要保留重复项,则必须使用UNION ALL,这不会消除重复项。所以SELECT 1 UNION ALL SELECT 1会导致:

+---+
| 1 |
+===+
| 1 |
+---+
| 1 |
+---+

另请注意,由于重复消除导致开销UNION ALL也是首选,如果知道该集合无论如何都不会有任何重复。您的示例就是这种情况-我们知道 {1, 2, 3, 4} 没有重复项。更好的选择也是如此SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4(尽管如此小的集合上的开销可能可以忽略不计)。

更多信息:“13.2.10.3 UNION 语法”


推荐阅读