如何将 SQL 中的 2 个表与 1 个公共列组合在一起,而其他列中没有关系?

Posted

技术标签:

【中文标题】如何将 SQL 中的 2 个表与 1 个公共列组合在一起,而其他列中没有关系?【英文标题】:How to combine 2 tables in SQL with 1 common column and no relation in the other columns? 【发布时间】:2019-09-27 00:35:12 【问题描述】:

我正在尝试将 2 个表与每个 2 列合并:

与城市合一 |姓名 与城市合一 |街道

每个表中的一列(Cities)包含类似的信息,但其他列(NamesStreets)在每个表中是独立的。

使用 common 列,我只想将下 2 列中的所有其他元素组合并列出为单个表格:

Cities | Names | Streets

列出原始表格中的所有NamesStreets,第一列中的City 正确,NamesStreets 不重复(如果有更多Names,则添加空格或Streets 在某个City

这里总结:

https://docs.google.com/spreadsheets/d/e/2PACX-1vQxHJopVBcuUN9RK5fHs7qhVxdry4v3HB6Az3LrRWXJxspV4abTTFS2VQka87GG3s9DHlT6FKUKPWal/pubhtml

我尝试了不同的连接,但我得到了NamesStreets 之间的所有组合,这不是我想要的。

这不起作用:

select *  
from city, street 
where city.city = street.city
order by city.name asc, street.name asc;

请在此处查看 Google 表格:https://docs.google.com/spreadsheets/d/e/2PACX-1vQxHJopVBcuUN9RK5fHs7qhVxdry4v3HB6Az3LrRWXJxspV4abTTFS2VQka87GG3s9DHlT6FKUKPWal/pubhtml

添加代码来创建表格,以防有人想尝试一下:

CREATE TABLE names  
(
    id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY, 
    city VARCHAR(30) NOT NULL, 
    name VARCHAR(30) NOT NULL
); 

CREATE TABLE streets 
(
    id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY, 
    city VARCHAR(30) NOT NULL, 
    street VARCHAR(30) NOT NULL
); 

INSERT INTO `names` (`id`, `city`, `name`) VALUES (1, 'paris', 'nameP1');
INSERT INTO `names` (`id`, `city`, `name`) VALUES (2, 'paris', 'nameP2');
INSERT INTO `names` (`id`, `city`, `name`) VALUES (3, 'paris', 'nameP3');
INSERT INTO `names` (`id`, `city`, `name`) VALUES (4, 'paris', 'nameP4');
INSERT INTO `names` (`id`, `city`, `name`) VALUES (5, 'paris', 'nameP5');
INSERT INTO `names` (`id`, `city`, `name`) VALUES (6, 'tokyo', 'nameT1');
INSERT INTO `names` (`id`, `city`, `name`) VALUES (7, 'tokyo', 'nameT2');
INSERT INTO `names` (`id`, `city`, `name`) VALUES (8, 'tokyo', 'nameT3');
INSERT INTO `names` (`id`, `city`, `name`) VALUES (9, 'tokyo', 'nameT4');
INSERT INTO `names` (`id`, `city`, `name`) VALUES (10, 'tokyo', 'nameT5');
INSERT INTO `names` (`id`, `city`, `name`) VALUES (11, 'tokyo', 'nameT6');

INSERT INTO `streets` (`id`, `city`, `street`) VALUES (1, 'paris', 'streetP1');
INSERT INTO `streets` (`id`, `city`, `street`) VALUES (2, 'paris', 'streetP2');
INSERT INTO `streets` (`id`, `city`, `street`) VALUES (3, 'paris', 'streetP3');
INSERT INTO `streets` (`id`, `city`, `street`) VALUES (4, 'tokyo', 'streetT1');
INSERT INTO `streets` (`id`, `city`, `street`) VALUES (5, 'tokyo', 'streetT2');
INSERT INTO `streets` (`id`, `city`, `street`) VALUES (6, 'tokyo', 'streetT3');
INSERT INTO `streets` (`id`, `city`, `street`) VALUES (7, 'tokyo', 'streetT4');
INSERT INTO `streets` (`id`, `city`, `street`) VALUES (8, 'tokyo', 'streetT5');
INSERT INTO `streets` (`id`, `city`, `street`) VALUES (9, 'tokyo', 'streetT6');
INSERT INTO `streets` (`id`, `city`, `street`) VALUES (10, 'tokyo', 'streetT7');
INSERT INTO `streets` (`id`, `city`, `street`) VALUES (11, 'tokyo', 'streetT8');
INSERT INTO `streets` (`id`, `city`, `street`) VALUES (12, 'tokyo', 'streetT9');
INSERT INTO `streets` (`id`, `city`, `street`) VALUES (13, 'tokyo', 'streetT10');

在此处添加我的表格和预期结果:

名称

+---—+-------+--------+
| id |  City |  Names | 
+---—+-------+--------+
|  1 | paris | nameP1 |
|  2 | paris | nameP2 |
|  3 | paris | nameP3 |
|  4 | paris | nameP4 |
|  5 | paris | nameP5 |
|  6 | tokyo | nameT1 |
|  7 | tokyo | nameT2 |
|  8 | tokyo | nameT3 |
|  9 | tokyo | nameT4 |
| 10 | tokyo | nameT5 |
| 11 | tokyo | nameT6 |
+---—+-------+--------+

餐桌街道

+----+-------+-----------+
| id |  City |   Streets | 
+----+-------+-----------+
|  1 | paris |  streetP1 |
|  2 | paris |  streetP2 |
|  3 | paris |  streetP3 |
|  4 | tokyo |  streetT1 |
|  5 | tokyo |  streetT2 |
|  6 | tokyo |  streetT3 |
|  7 | tokyo |  streetT4 |
|  8 | tokyo |  streetT5 |
|  9 | tokyo |  streetT6 |
| 10 | tokyo |  streetT7 |
| 11 | tokyo |  streetT8 |
| 12 | tokyo |  streetT9 |
| 13 | tokyo | streetT10 |
+----+-------+-----------+

预期结果:

+-------+---------+-----------+
| City  | Names   | Streets   |
+-------+---------+-----------+
| paris |  nameP1 |  streetP1 |
| paris |  nameP2 |  streetP2 |
| paris |  nameP3 |  streetP3 |
| paris |  nameP4 |           |
| paris |  nameP5 |           |
| tokyo |  nameT1 |  streetT1 |
| tokyo |  nameT2 |  streetT2 |
| tokyo |  nameT3 |  streetT3 |
| tokyo |  nameT4 |  streetT4 |
| tokyo |  nameT5 |  streetT5 |
| tokyo |  nameT6 |  streetT6 |
| tokyo |         |  streetT7 |
| tokyo |         |  streetT8 |
| tokyo |         |  streetT9 |
| tokyo |         | streetT10 |
+-------+---------+-----------+

请注意:

表 'names' 列出了 5 个在巴黎的名字,6 个在东京的名字 表“街道”列出了巴黎的 3 条街道、东京的 10 条街道 结果应在第 1 列中列出 2 个城市,在巴黎旁边的接下来的 2 列中列出巴黎的 5 个名称和 3 条街道,然后是东京旁边的东京的 6 个名称和 10 条街道 名称和街道之间没有关系,除非它们在同一个城市中 巴黎的名字比街道多,东京的街道比名字多,所以一些值留空以适应这种情况

在下面跟进 Gordon 的回答:几乎就在那里,但不是 100%,因为我想保持这座城市的行列。 如果我在党派中有更多的街道,那就不完全是 - 请参阅:

如果我开始:

创建表名称 ( id INT(6) 未签名的 AUTO_INCREMENT 主键, 城市 VARCHAR(30) 非空, 名称 VARCHAR(30) 非空 );

创建表格街道( id INT(6) 未签名的 AUTO_INCREMENT 主键, 城市 VARCHAR(30) 非空, 街道 VARCHAR(30) 非空 );

插入names (id, city, name) 值 (1, 'paris', 'nameP1'); 插入names (id, city, name) 值 (2, 'paris', 'nameP2'); 插入names (id, city, name) 值 (3, 'paris', 'nameP3'); 插入names (id, city, name) 值 (4, 'paris', 'nameP4'); 插入names (id, city, name) 值 (5, 'paris', 'nameP5'); 插入names (id, city, name) 值 (6, 'tokyo', 'nameT1'); 插入names (id, city, name) 值 (7, 'tokyo', 'nameT2'); 插入names (id, city, name) 值 (8, 'tokyo', 'nameT3'); 插入names (id, city, name) 值 (9, 'tokyo', 'nameT4'); 插入names (id, city, name) 值 (10, 'tokyo', 'nameT5'); 插入names (id, city, name) 值 (11, 'tokyo', 'nameT6');

插入streets (id, city, street) 值 (1, 'paris', 'streetP1'); 插入streets (id, city, street) 值 (2, 'paris', 'streetP2'); 插入streets (id, city, street) 值 (3, 'paris', 'streetP3'); 插入streets (id, city, street) 值 (3, 'paris', 'streetP4'); 插入streets (id, city, street) 值 (3, 'paris', 'streetP5'); 插入streets (id, city, street) 值 (3, 'paris', 'streetP6'); 插入streets (id, city, street) 值 (3, 'paris', 'streetP7'); 插入streets (id, city, street) 值 (4, 'tokyo', 'streetT1'); 插入streets (id, city, street) 值 (5, 'tokyo', 'streetT2'); 插入streets (id, city, street) 值 (6, 'tokyo', 'streetT3'); 插入streets (id, city, street) 值 (7, 'tokyo', 'streetT4'); 插入streets (id, city, street) 值 (8, 'tokyo', 'streetT5'); 插入streets (id, city, street) 值 (9, 'tokyo', 'streetT6'); 插入streets (id, city, street) 值 (10, 'tokyo', 'streetT7'); 插入streetsidcitystreet)值(11,'东京','streetT8'); 插入streets (id, city, street) 值 (12, 'tokyo', 'streetT9'); 插入streets (id, city, street) 值 (13, 'tokyo', 'streetT10');

我正在创建这两个表:

表名称 +——————+——-——-——+——————————+ |编号 |城市 |姓名 | +——+————————+——-————+ | 1 |巴黎 |名称P1 | | 2 |巴黎 |名称P2 | | 3 |巴黎 |名称P3 | | 4 |巴黎 |名称P4 | | 5 |巴黎 |名称P5 | | 6 |东京 |名称T1 | | 7 |东京 |名称T2 | | 8 |东京 |名称T3 | | 9 |东京 |名称T4 | | 10 |东京 |名称T5 | | 11 |东京 |名称T6 | +——+————————+——-————+

餐桌街道 +——-——+————————+————————————+ |编号 |城市 |街道 | +——-——+————————+——————————+ | 1 |巴黎 |街道P1 | | 2 |巴黎 |街道P2 | | 3 |巴黎 |街道P3 | | 4 |巴黎 |街道P4 | | 5 |巴黎 |街道P5 | | 6 |巴黎 |街道P6 | | 7 |巴黎 |街道P7 | | 8 |东京 |街道T1 | | 9 |东京 |街道T2 | | 10 |东京 |街道T3 | | 11 |东京 |街道T4 | | 12 |东京 |街道T5 | | 13 |东京 |街道T6 | | 14 |东京 |街道T7 | | 15 |东京 |街道T8 | | 16 |东京 |街道T9 | | 17 |东京 |街道T10 | +———+———-———+———-———-———+

我想得到:

+——-——-——+————————+——-——-——-——+ |城市 |姓名 |街道 | +————————+————————+————————————+ |巴黎 |名称P1 |街道P1 | |巴黎 |名称P2 |街道P2 | |巴黎 |名称P3 |街道P3 | |巴黎 |名称P4 |街道P4 | |巴黎 |名称P5 |街道P5 | |巴黎 | |街道P6 | |巴黎 | |街道P7 | |东京 |名称T1 |街道T1 | |东京 |名称T2 |街道T2 | |东京 |名称T3 |街道T3 | |东京 |名称T4 |街道T4 | |东京 |名称T5 |街道T5 | |东京 |名称T6 |街道T6 | |东京 | |街道T7 | |东京 | |街道T8 | |东京 | |街道T9 | |东京 | |街道T10 | +——-——-——+————-———+———-——-——-——+

但是根据 Gordon 在下面的初步回应,我得到了:

+——-——-——+————————+——-——-——-——+ |城市 |姓名 |街道 | +————————+————————+————————————+ |巴黎 |名称P1 |街道P1 | |巴黎 |名称P2 |街道P2 | |巴黎 |名称P3 |街道P3 | |巴黎 |名称P4 |街道P4 | |巴黎 |名称P5 |街道P5 | |东京 |名称T1 |街道T1 | |东京 |名称T2 |街道T10 | |东京 |名称T3 |街道T2 | |东京 |名称T4 |街道T3 | |东京 |名称T5 |街道T4 | |东京 |名称T6 |街道T5 | |巴黎 | |街道P6 | |巴黎 | |街道P7 | |东京 | |街道T6 | |东京 | |街道T7 | |东京 | |街道T8 | |东京 | |街道T9 | +——-——-——+————-———+———-——-——-——+

有什么想法吗?似乎只是某个地方的订购问题,但我无法弄清楚....谢谢!

【问题讨论】:

可以分享city和street表的表结构以及一些示例数据吗? 当然 - 我刚刚在上面添加了这个 - 谢谢 请显示您想要的结果。 请不要在特别需要登录的链接中发布,因为它们可能会破坏未来的读者。在帖子正文中包含所有内容。 知道了 - 我现在已经尝试将表格和预期结果内联在上面,但我正在为格式化而苦苦挣扎……抱歉…… 【参考方案1】:

我猜你想要“垂直”列表。这并不是 SQL 的真正工作方式,但您可以使用 row_number() 和聚合来做到这一点:

select city, max(name) as name, max(street) as street
from ((select city, name, null as street,
              row_number() over (partition by city order by name) as seqnum
       from names
      ) union all
      (select city, null, street,
              row_number() over (partition by city order by street) as seqnum
       from streets
      )
     ) sn
group by city, seqnum
order by city, seqnum;

【讨论】:

天啊——正是我要找的东西!!!非常感谢!我什至不知道你是怎么理解我的问题的,但你没问题!这是一个巨大的帮助,非常感谢! 顺便说一句:只是一个小细节,但上面的第二个“来自名称”应该是“来自街道”——提一下以防其他人尝试这样做 @DominiqueBouchon 。 . .谢谢。 嗨,戈登,关于这个问题的另一个快速问题:我注意到如果我在巴黎的街道比东京多,那么您的查询不会将所有巴黎的行放在一起 - 我不太明白为什么,但是一旦巴黎的名字被相同数量的巴黎街道填满,它就会切换到东京的名字和街道,然后回到以“空”名字开头的巴黎......也许这就是“最大”的方式与 order by 一起使用?任何的想法?在上面查看我的最后编辑... @DominiqueBouchon 。 . .我认为您可能只需要订购结果。【参考方案2】:

也许我错了,但你不是只寻找内连接查询吗?

select city.cities, city.names, street.streets from city inner join street on city.cities=street.cities

【讨论】:

感谢您的回答 - 不完全是,内部连接实际上会为其公共城市创建名称和街道的所有组合。在我的情况下,我希望名称和街道只出现一次,与城市对齐,在与其城市对应的街区的名称和街道列的顶部... 显示而不是告诉你的输出。像英语这样的自然语言可能不精确,而数据说明效果更好。

以上是关于如何将 SQL 中的 2 个表与 1 个公共列组合在一起,而其他列中没有关系?的主要内容,如果未能解决你的问题,请参考以下文章

如何将没有公共列的 2 个表合并到 SSIS 中的 1 个表中?

如何将两个表与 SQL Server 中第二个表中引用同一列的两列连接起来

MS Access sql将5个表与列中的奇怪字符分组

如何将 2 个表与日期进行比较并检查缺少哪个日期并使用 Mysql 插入日期?

多个表与一个具有更多列的表

如何组合来自4个mysql表的数据