【问题标题】:Combining duplicate SQLite columns after joining parent with multiple children将父级与多个子级连接后合并重复的 SQLite 列
【发布时间】:2020-12-17 02:29:45
【问题描述】:

我设置了一个 SQLite 数据库,如下所示:

我目前正在寻找将所有子表加入到父表中。正如你所看到的,所有的孩子都是以同样的方式设计的,所以我希望他们能很好地融合在一起。
不幸的是,使用左连接加入表会导致:

使用SQLite,是否可以合并列,从而忽略空值,而剩余的starting_item_ids和item_ids都显示在同一列中?

任何帮助将不胜感激。

编辑:这是一个最小的可重现示例

CREATE TABLE `starting_item` (
  `starting_item_id` integer PRIMARY KEY AUTOINCREMENT,
  `quantity` integer
);

CREATE TABLE `starting_weapon` (
  `starting_item_id` integer,
  `item_id` integer,
  FOREIGN KEY (`starting_item_id`) REFERENCES `starting_item` (`starting_item_id`)
);

CREATE TABLE `starting_armor` (
  `starting_item_id` integer,
  `item_id` integer,
  FOREIGN KEY (`starting_item_id`) REFERENCES `starting_item` (`starting_item_id`)
);

CREATE TABLE `starting_gear` (
  `starting_item_id` integer,
  `item_id` integer,
  FOREIGN KEY (`starting_item_id`) REFERENCES `starting_item` (`starting_item_id`)
);

CREATE TABLE `starting_tool` (
  `starting_item_id` integer,
  `item_id` integer,
  FOREIGN KEY (`starting_item_id`) REFERENCES `starting_item` (`starting_item_id`)
);


INSERT INTO starting_item (quantity) VALUES (1);
INSERT INTO starting_item (quantity) VALUES (1);
INSERT INTO starting_item (quantity) VALUES (1);
INSERT INTO starting_item (quantity) VALUES (1);


INSERT INTO starting_weapon (starting_item_id, item_id) VALUES (1, 4);
INSERT INTO starting_armor (starting_item_id, item_id) VALUES (2, 7);
INSERT INTO starting_gear (starting_item_id, item_id) VALUES (3, 30);
INSERT INTO starting_tool (starting_item_id, item_id) VALUES (4, 20);


select * from starting_item 
    left join starting_weapon on starting_weapon.starting_item_id = starting_item.starting_item_id
    left join starting_armor on starting_armor.starting_item_id = starting_item.starting_item_id
    left join starting_gear on starting_gear.starting_item_id = starting_item.starting_item_id
    left join starting_tool on starting_tool.starting_item_id = starting_item.starting_item_id

当前结果:

+------------------+----------+------------------+---------+------------------+---------+------------------+---------+------------------+---------+
| starting_item_id | quantity | starting_item_id | item_id | starting_item_id | item_id | starting_item_id | item_id | starting_item_id | item_id |
+------------------+----------+------------------+---------+------------------+---------+------------------+---------+------------------+---------+
|                1 |        1 |                1 |       4 |                  |         |                  |         |                  |         |
+------------------+----------+------------------+---------+------------------+---------+------------------+---------+------------------+---------+
|                2 |        1 |                  |         | 2                | 7       |                  |         |                  |         |
+------------------+----------+------------------+---------+------------------+---------+------------------+---------+------------------+---------+
|                3 |        1 |                  |         |                  |         | 3                | 30      |                  |         |
+------------------+----------+------------------+---------+------------------+---------+------------------+---------+------------------+---------+
|                4 |        1 |                  |         |                  |         |                  |         | 4                | 20      |
+------------------+----------+------------------+---------+------------------+---------+------------------+---------+------------------+---------+

预期结果:

+------------------+----------+------------------+---------+
| starting_item_id | quantity | starting_item_id | item_id |
+------------------+----------+------------------+---------+
|                1 |        1 |                1 |       4 |
+------------------+----------+------------------+---------+
|                2 |        1 |                2 |       7 |
+------------------+----------+------------------+---------+
|                3 |        1 |                3 |      30 |
+------------------+----------+------------------+---------+
|                4 |        1 |                4 |      20 |
+------------------+----------+------------------+---------+

【问题讨论】:

  • 请阅读 SQLite 标签信息并提供minimal reproducible example,如那里所述。 stackoverflow.com/tags/sqlite/info 通常请以文字形式提供文字信息,而不是(仅)作为文字图片。确保为提供的定制玩具数据库提供所需的结果。
  • 请仔细检查。我怀疑您显示的预期结果不是您真正想要的。我不想要重复的列,我想要指示“item_id”来自哪个子表,即工具、装备、盔甲或武器。请理解,我想我可以编写一个查询来产生当前所需的结果,但我希望你能改变主意。这将成为一个(不受欢迎的)“移动目标问题”。
  • 顺便说一句,如果我提供一个答案,我不会为花哨的“框架”和专栏标题而烦恼。请说明它们是否必不可少。它们有助于理解和可读性,因此请保留它们。只需说明它们是否是必需的。
  • 这能回答你的问题吗? MySQL combine two columns into one column
  • @Jere 我挑战你的副本。对于与 OP 所示结构相似的表,不恰当地修改字符串操作。我将在几个小时内做出答复。希望到那时问题还没有结束,并且到那时所需的输出更有说服力。

标签: sql sqlite


【解决方案1】:

您可以通过以下查询获得所需的输出(减去帧,但这只是一个配置):

select * from starting_item a
join (      select * from starting_weapon
      union select * from starting_armor
      union select * from starting_gear
      union select * from starting_tool) b
on a.starting_item_id=b.starting_item_id;

它使用结构相同的子表的多个“联合”,并使用别名“a”和“b”将其与起始项目表连接起来。

结果与声明的期望输出完全一致:

starting_item_id  quantity    starting_item_id  item_id
----------------  ----------  ----------------  ----------
1                 1           1                 4
2                 1           2                 7
3                 1           3                 30
4                 1           4                 20

但是,在我看来,避免冗余列(ID 的两倍)是可取的。
而且我也觉得添加指标(我们看到什么样的项目)的小技巧是有帮助的。所以我提供这个是为了漂亮:

select * from starting_item
join (      select *, "weapon" kind from starting_weapon
      union select *, "armor"  kind from starting_armor
      union select *, "gear"   kind from starting_gear
      union select *, "tool"   kind from starting_tool)
using(starting_item_id);

如果你喜欢它,它会得到你:

starting_item_id  quantity    item_id     kind
----------------  ----------  ----------  ----------
1                 1           4           weapon
2                 1           7           armor
3                 1           30          gear
4                 1           20          tool

第一个变化是加入using() 而不是on ...,这(尽管为了方便使用* )只会得到一个ID 列。
第二个更改是在每个“联合”部分中添加一个名为“kind”的列,其中包含明确给出的内容。这个“联合”和“加入”很好地结合起来,为您提供一个命名的指标列。优点是您可以例如按该指示列排序以保持整洁。

最后,请考虑这里使用的联合表是否实际上不是您可以在数据库设计中使用的东西。 IE。对所有项目使用一个表,并附加一个“种类”列。

【讨论】:

  • 非常感谢,Yunnosch,我最终加入了更多表格,并按照@DinoCoderSaurus 的建议使用了您的代码和合并函数,以从最终结果中得到我想要的。为您的所有帮助干杯。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-17
  • 2017-05-30
  • 2020-07-05
相关资源
最近更新 更多