【问题标题】:Many to one merging sql多对一合并sql
【发布时间】:2019-07-25 20:58:17
【问题描述】:

我有如下三张表:

First Table           Second Table    Third Table 
Name   PIN            Id   City         City_id  
David  1948           1    Roma          3
Susan  1245           2    Berlin        2
Jack   1578           3    New York      3
Hans   1247                              2
Rose   8745                              1

我想根据第三张表合并第一张和第二张表。结果将是:人

Name  PIN  City
David 1948 New York
Susan 1245 Berlin
Jack  1578 New York
Hans  1247 Berlin
Rose  8745 Roma

首先我可以合并第二个和第三个表,然后将结果表与第一个表合并,但我想在没有中表的情况下解决这个问题。我该如何处理?如何根据第三个表将第一个表的行与第二个表中的指定行顺序组合?

【问题讨论】:

  • 除非在第一个和第三个表中都有一个列(或列的组合)来定义顺序,否则您不能这样做。从您所展示的内容来看,似乎没有这样的列。
  • 我假设您的第三张表列出了与第一张表中的每个名称相关联的 City_id。除非您有一个外键将第一个表的记录与第三个表的记录相关联,否则这将不起作用。关系型数据库不支持假设记录顺序,所以你需要在第三个表中有另一列与第一个记录的ID。而且您应该在第一个表中添加一个 ID 列,因为您可以轻松拥有多个 David(我怀疑我是您所指的大卫。
  • 不用担心顺序你可以简单地认为第三张表按顺序显示第一张表的城市id。我当然可以直接合并第一张和第三张表,然后我可以将结果表与第二张连接起来使用 ids 的表,但我想在不使用中表的情况下解决这个问题。
  • 你不明白——SQL中没有“按顺序”的概念。您不能依赖表 1 和表 3 的顺序相同。在 SQL 中,必须有一些东西将记录绑定在一起 - 而不是您认为它们可能出现在表中的顺序。
  • 别担心,但请尝试了解关系数据库的工作原理:它们需要唯一的记录标识符。可以这样想:数据库不需要以任何特定顺序存储您的数据,因此它可能会将您的记录 Jack 放置在它存储 Susan 之前的空闲位置。如果您在选择记录时未指定ORDER BY 子句,则无法保证它们将按原始顺序显示。 SQL 没有理由支持这一点,因为规则要求您在需要时指定顺序。

标签: sql join merge set


【解决方案1】:

您需要使用 PersonID 和 CityID 链接在一起的第四个表 PersonCity。将关系数据库想象成网格(电子表格、道路)。如果您向北行驶并且您想要上的街道是平行的(想想|^| |^|),您将需要使用连接两者的不同道路。目前,您没有这样的路径。

【讨论】:

  • 不幸的是,在这种情况下,“电子表格”类比不适合,因为在电子表格中,行的顺序是确定的,但是 OP 无法理解在数据库中的顺序表中的记录数是不确定的。
  • 电子表格是网格的一个示例,拥有多个表格需要链接至少一列中的值以进行关联——这是关系数据库如何工作的经典示例。我知道他们的印象是记录顺序是确定的,但实际有用的信息是理解参考资料,对吗?这就是为什么我试图以这种方式解决它:)
【解决方案2】:

简短的回答是您的表格不足以完成任务,您需要的是:

Table_1                   Table_2          Table_3 
Id  Name   PIN            Id   City        Name_id City_id  
1   David  1948           1    Roma        1        3
2   Susan  1245           2    Berlin      2        2
3   Jack   1578           3    New York    3        3
4   Hans   1247                            4        2
5   Rose   8745                            5        1  

然后您可以按照以下方式进行查询:

   SELECT T1.Name, T1.PIN, T2.City
       FROM Table_1 T1 LEFT JOIN Table_3 T2 ON T1.Id = T3.Name_id
       LEFT JOIN Table_2 ON T3.City_id = T2.Id
       ORDER BY T1.Name

或者你可以ORDER BY城市,名字

【讨论】:

  • 你的意思是? SELECT T1.Name, T1.PIN, T2.City FROM Table_1 T1 LEFT JOIN Table_3 T3 ON T1.Id = T3.Name_id LEFT JOIN Table_2 ON T3.City_id = T2.Id ORDER BY T1.Name
  • 对不起,是的,我编辑了我的答案以修复表号。
  • 除非一个人(table1)可以关联多个城市(table2),否则city_id可以直接进入table_1table_3可以一起删除.
  • 粘滞位:确实如此,但我会“假设”城市表可能会在某些时候添加其他信息,这将证明数据库规范化是合理的。
【解决方案3】:

我有好消息和坏消息。

好消息,按照最初指定的方式,在 Oracle 中,这会给你一些看起来像你问的东西:

---
--- Pay attention, This looks right but it is not!
---
select name,pin,city from
  ( select name,pin,rownum rn from first ) a,
  ( select city,id from second) b,
  ( select id,rownum rn from third  ) c
  where
  a.rn=c.rn AND
  b.id=c.id;

NAME                     PIN  CITY
-------------------- ---- --------------------
Rose                     8745 Roma
Susan                    1245 Berlin
Hans                     1247 Berlin
David                    1948 New York
Jack                     1578 New York

坏消息是这并没有真正起作用并且是在作弊。你会得到结果,但它们可能不是你所期望的,也不一定是一致的。

数据库按自己的顺序排列记录。如果您不指定order by 子句,您将得到他们给您的,这可能不是您想要的。这是作弊,因为 Oracle 不真正 支持以这种方式使用 rownum,因为你不能赌你会得到什么。这在大多数其他数据库中不起作用。

唯一正确的方法是@daShier 给出的方法,您必须在其中添加一些东西,例如 ID,以允许按照您想要的顺序连接行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-28
    • 1970-01-01
    • 2012-02-07
    • 1970-01-01
    • 1970-01-01
    • 2017-12-04
    • 1970-01-01
    • 2021-11-12
    相关资源
    最近更新 更多