如何将 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
)包含类似的信息,但其他列(Names
和Streets
)在每个表中是独立的。
使用 common 列,我只想将下 2 列中的所有其他元素组合并列出为单个表格:
Cities | Names | Streets
列出原始表格中的所有Names
和Streets
,第一列中的City
正确,Names
或Streets
不重复(如果有更多Names
,则添加空格或Streets
在某个City
。
这里总结:
https://docs.google.com/spreadsheets/d/e/2PACX-1vQxHJopVBcuUN9RK5fHs7qhVxdry4v3HB6Az3LrRWXJxspV4abTTFS2VQka87GG3s9DHlT6FKUKPWal/pubhtml
我尝试了不同的连接,但我得到了Names
和Streets
之间的所有组合,这不是我想要的。
这不起作用:
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');
插入streets
(id
,city
,street
)值(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 中第二个表中引用同一列的两列连接起来