【问题标题】:How to select null when the record does not exist with UNION ALL?UNION ALL不存在记录时如何选择null?
【发布时间】:2018-08-04 11:45:49
【问题描述】:

我有一本书,里面有数百名学生的记录,每个学生都有一个身份证号码,后跟名字和姓氏。

我需要提取更多信息,例如出生日期、性别等。为此,我有一个 Student 表,其中存储了我需要的所有信息(因此我不需要任何 JOIN与其他表),所以我想在 excel 中执行 rune 函数,将查询连接起来,然后是 UNION:

=CONCATENAR("SELECT * FROM (SELECT TOP 1 Std_Identification, Std_Gender, Std_BirthDate FROM Student WHERE Std_Identification='";A1;"') AS T UNION ALL")

但是,标识号可能已过时,因此记录不完整(如果我用 200 条记录进行查询,他们可以留下 190 条),它们的差异很小,但我需要多次执行此任务,我想要的是这个:

+--------------------+------------+---------------+
| Std_Identification | Std_Gender | Std_BirthDate |
+--------------------+------------+---------------+
|      34998545      |      0     |   12/05/1997  |
+--------------------+------------+---------------+
|      12443334      |     NULL   |      NULL     |  <- This record NOT exists in the table Student
+--------------------+------------+---------------+
|      39405443      |      1     |   21/09/1980  |
+--------------------+------------+---------------+

我尝试了以下查询,但仍然没有成功:

SELECT * FROM (SELECT TOP 1 Std_Identification, Std_Gender, Std_BirthDate FROM Student WHERE Std_Identification='34998545') AS T UNION ALL
SELECT * FROM (SELECT TOP 1 Std_Identification, Std_Gender, Std_BirthDate FROM Student WHERE Std_Identification='12443334') AS T UNION ALL
SELECT * FROM (SELECT TOP 1 Std_Identification, Std_Gender, Std_BirthDate FROM Student WHERE Std_Identification='39405443') AS T

但结果是:

+--------------------+------------+---------------+
| Std_Identification | Std_Gender | Std_BirthDate |
+--------------------+------------+---------------+
|      34998545      |      0     |   12/05/1997  |
+--------------------+------------+---------------+
|      39405443      |      1     |   21/09/1980  |
+--------------------+------------+---------------+
  • 如何让 SELECT UNION 显示 NULL 而不是空白 什么时候记录不存在?
  • 是否可以这样做,但是当我需要一个 JOIN 与多个 表?假设我需要提取 在另一个表 X 中(因此由于在 表 Student 和表 X),但并非所有学生都有代码或 记录以将其与该表相关联X

【问题讨论】:

  • 尝试使用 [(select 34998545 ID ) left join Std_identification]

标签: sql sql-server database select null


【解决方案1】:

只需将您需要的值分配给相关列

SELECT * FROM (SELECT TOP 1 Std_Identification, Std_Gender, Std_BirthDate 
        FROM Student WHERE Std_Identification='34998545') AS T UNION ALL
SELECT  '12443334', NULL, NULL  UNION ALL
SELECT * FROM (SELECT TOP 1 Std_Identification, Std_Gender, Std_BirthDate 
        FROM Student WHERE Std_Identification='39405443') AS T

或者你可以在同一个表上使用左连接,在条件下应用过滤器。这样,如果你有 200 名学生,你会检索 200 行,包括不匹配过滤器的行

select distinct a.Std_Identification 
from Student a
left join stundent b on a.Std_Identification = b.Std_Identification 
        AND b.Std_Gender = 'M'

【讨论】:

  • 哦,不,我想我不太了解:p 我有学生名单,但我不知道表中具体存在与否,这就是为什么我决定向所有人咨询一个 SELECT UNION,我意识到如果我咨询其中的 200 个,我得到 190 个),我想要以我咨询他们的相同顺序向我展示失踪的学生(在 NULL 中的行,如 '12443334' 的示例)然后将结果复制并粘贴到 Excel 书中,无需移动任何内容
  • 这行不通我的朋友:'(,看来最好的办法是将身份证明文件从最小到最大的Excel文件组织起来,然后在另一张具有相同信息的工作表上像我目前正在做的那样有组织地搜索数据库中的文档,在获得 SSMS 发送给我的结果后,我必须过滤文档列中的重复记录,其余记录(不重复)手动查找它们,之后从最小到最大组织记录,其中一些我将完成我的目标。
  • 我不明白你的评论.is。复杂..我不在您的代码处理中,所以我无法理解您在做什么..我仅基于您在上面的问题中提供的示例。
【解决方案2】:

很久以前就有这个问题了,问题是我需要的数据是SQL Server数据库,但是从学生的身份来看,Excel中数据的顺序很重要,因为我需要粘贴新的电子表格上的数据。

某些数据不存在(因为标识不在数据库中)因此我不能省略它,为此我使用了 SELECT UNION,这导致它最终返回的行数较少。

当时我发现的最简单的解决方案是在电子表格 (Excel) 中为每行创建一个公式,以将行插入到临时表中:

=CONCATENAR("INSERT INTO @TempTable(Id) VALUES('";A1;"');")

然后进行 OUTER APPLY,类似于 LEFT JOIN 结合 TOP 1,这样可以让我拥有最新的记录,因为在表中可以有多个具有相同标识的记录:

DECLARE @TempTable TABLE ( Id VARCHAR(20) NULL );

// paste your inserts into from Excel

SELECT T.Id, SS.Std_Identification, SS.Std_Gender, SS.Std_BirthDate 
FROM @TempTable T
OUTER APPLY
( 
    SELECT TOP 1 S.Std_Identification, S.Std_Gender, S.Std_BirthDate 
    FROM Student S 
    WHERE S.Std_Identification = T.Id
    ORDER BY S.CreationDate DESC 
) AS SS

【讨论】:

    【解决方案3】:

    如果我理解正确,

    1)在数据库上创建一个临时表,其中包含一列studentid。

    2) 写入 INSERT INTO temptable VALUES ("A1") 并将 INSERT 公式复制到所有行。这样,您可以创建一个包含所有 id 的 INSERT INTO 脚本。

    3) 将临时表左连接到学生表,所有不在学生表中的记录都将显示为NULL。Row_Number() 可用于根据条件过滤掉重复的。

    编辑1:

    我无法回复您的评论,所以我在这里进行编辑。

    APPLY 也可以使用。 如果你想使用 LEFT JOIN ,可以使用 Row_number() 来过滤掉基于日期的欺骗

    SELECT T.Id, SS.Std_Identification, SS.Std_Gender, SS.Std_BirthDate
    FROM
    @TempTable T
    LEFT JOIN 
      (SELECT 
       S.Std_Identification, S.Std_Gender, S.Std_BirthDate,ROW_NUMBER() OVER       
       (PARTITION BY S.Std_Identification ORDER BY S.CreationDate DESC ) AS RN
      )S
     ON
     T.Id=S S.Std_Identification
     WHERE S.RN=1
    

    【讨论】:

    • LEFT JOIN 也很有用,尽管在我的情况下,我在 Students 表中有具有相同 ID 的记录,但在执行 LEFT JOIN 时,当我真的想要一个时,我会使用该标识符连接所有行记录(最近的),所以我使用 OUTER APPLY 按日期排序
    猜你喜欢
    • 2013-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多