sql - 是否可以将一个表中的 SELECT 与另一表中的另一个 SELECT 连接到一行中?

标签 sql sql-server database select

我有一个名为“Studies”的表格,它有以下几列:

+-------------+---------------+-------------+------------+-------------+
| CodeStudent |   Type Study  | Title Study | Date Study | Place Study |
+-------------+---------------+-------------+------------+-------------+
|  10         |   Technical   |   TitleOne  | 01-02-2005 |    Narnia   |
+-------------+---------------+-------------+------------+-------------+
|  10         | Technological |   TitleTwo  | 01-05-2009 |    Mars     |
+-------------+---------------+-------------+------------+-------------+
|  10         |   University  |  TitleThree | 01-08-2012 | Gotham City |
+-------------+---------------+-------------+------------+-------------+
|  20         |   Technical   |  OtherTitle | 01-06-2011 |    Namek    |
+-------------+---------------+-------------+------------+-------------+

我有一个名为“学生”的表,其中包含以下列和信息:

+-------------+---------------+-------------+------------+
| CodeStudent |      Name     |   LastName  |  BirthDate |  
+-------------+---------------+-------------+------------+
|  10         |      Hug      |   Lobezno   | 02-02-2002 |
+-------------+---------------+-------------+------------+
|  20         |      Son      |    Gokú     | 05-06-2007 |
+-------------+---------------+-------------+------------+

应考虑以下因素:

  • “Students”表的 CodeStudent 列是主键,“Studies”表的 CodeStudent 列是其各自的外键
  • 唯一存在的研究类型是技术、科技和大学
  • 需要指出的是,并非所有学生都拥有三种类型的学习(技术、技术和大学),其中一些学生可能有两项学习、一项学习(如孙悟空学生的情况)或没有。

我是否需要知道是否可以在一行中显示所有信息?

如果请求代码为 10 的学生信息,则应显示以下内容:

+-------------+---------------+-------------+------------+-----------------+---------------+----------------+--------------------+-------------------+--------------------+-----------------+----------------+-----------------+
| CodeStudent |      Name     |   LastName  |  BirthDate |  TitleTechnical | DateTechnical | PlaceTechnical | TitleTechnological | DateTechnological | PlaceTechnological | TitleUniversity | DateUniversity | PlaceUniversity |
+-------------+---------------+-------------+------------+-----------------+---------------+----------------+--------------------+-------------------+--------------------+-----------------+----------------+-----------------+
|  10         |      Hug      |   Lobezno   | 02-02-2002 |    TitleOne     |   01-02-2005  |     Narnia     |      TitleTwo      |    01-05-2009     |        Mars        |    TitleThree   |   01-08-2012   |    Gotham City  |
+-------------+---------------+-------------+------------+-----------------+---------------+----------------+--------------------+-------------------+--------------------+-----------------+----------------+-----------------+

如果请求代码为 20 的学生信息,则应显示以下内容:

+-------------+---------------+-------------+------------+-----------------+---------------+----------------+--------------------+-------------------+--------------------+-----------------+----------------+-----------------+
| CodeStudent |      Name     |   LastName  |  BirthDate |  TitleTechnical | DateTechnical | PlaceTechnical | TitleTechnological | DateTechnological | PlaceTechnological | TitleUniversity | DateUniversity | PlaceUniversity |
+-------------+---------------+-------------+------------+-----------------+---------------+----------------+--------------------+-------------------+--------------------+-----------------+----------------+-----------------+
|  20         |      Son      |   Goku      | 05-06-2007 |    OtherTitle   |   01-06-2011  |     Namek      |       NULL         |       NULL        |        NULL        |       NULL      |      NULL      |       NULL      |
+-------------+---------------+-------------+------------+-----------------+---------------+----------------+--------------------+-------------------+--------------------+-----------------+----------------+-----------------+

我知道有一种方法,那就是:

SELECT
      S.CodeStudent, 
      S.Name,
      S.LastName,
      S.BirthDate, 
      (SELECT TOP 1 ST.TitleStudy FROM Studies ST WHERE ST.CodeStudent = 10 AND ST.TypeStudy = 'Technical') AS TitleTechnical,
      (SELECT TOP 1 ST.DateStudy FROM Studies ST WHERE ST.CodeStudent = 10 AND ST.TypeStudy = 'Technical') AS DateTechnical,
      ...
FROM Student S
WHERE S.CodeStudent = 10

但是有没有更好、最优的方法来做到这一点? :p

最佳答案

使用条件聚合来旋转每种研究类型的列集:

select
    S.CodeStudent
  , S.Name
  , S.LastName
  , S.BirthDate
  , TitleTechnical     = max(case when t.TypeStudy = 'Technical' then t.TitleStudy end)
  , DateTechnical      = max(case when t.TypeStudy = 'Technical' then t.DateStudy end)
  , PlaceTechnical     = max(case when t.TypeStudy = 'Technical' then t.PlaceStudy end)
  , TitleTechnological = max(case when t.TypeStudy = 'Technological' then t.TitleStudy end)
  , DateTechnological  = max(case when t.TypeStudy = 'Technological' then t.DateStudy end)
  , PlaceTechnological = max(case when t.TypeStudy = 'Technological' then t.PlaceStudy end)
  , TitleUniversity    = max(case when t.TypeStudy = 'University' then t.TitleStudy end)
  , DateUniversity     = max(case when t.TypeStudy = 'University' then t.DateStudy end)
  , PlaceUniversity    = max(case when t.TypeStudy = 'University' then t.PlaceStudy end)
from Student S
  left join Studies T  -- left join to support querying students with no studies
    on s.CodeStudent = t.CodeStudent
where S.CodeStudent = 10
group by 
    S.CodeStudent
  , S.Name
  , S.LastName
  , S.BirthDate

rextester 演示:http://rextester.com/SJONU26439

关于sql - 是否可以将一个表中的 SELECT 与另一表中的另一个 SELECT 连接到一行中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47146661/

相关文章:

database - 有谁知道一个很好的图书馆可以将一个人的名字映射到他或她的性别?

PHP range & foreach,使用当前值? (WordPress)

mysql - 如何将列的默认值设置为今天的日期?

sql - 使用 Dapper 将 SQL 查询转换为 IList<T>

python - 如何将 Google App Engine 与 MS-SQL 一起使用

c# - SQL逻辑放在哪里

MySQL 使用主键删除重复行

sql - 渐进搜索最长前缀

sql-server - INSTEAD OF INSERT、UPDATE 触发器的更好替代方案

mysql - 我是否应该对表进行非规范化,是否应该对 FK 列进行非规范化