【问题标题】:Make an alias column from 2 different tables in MySQL从 MySQL 中的 2 个不同的表中创建一个别名列
【发布时间】:2019-03-28 10:03:00
【问题描述】:

我有一个与 2 个不同表相关的数据库表,例如:

   === inventory ===
+------------+-----------+
|    code    |   total   |
+------------+-----------+
| el_pr_25   |     45    |
| el_pr_11   |     33    |
| mob_tp_x93 |     23    |
| mob_tp_t55 |     33    |
| el_pr_x73  |     25    |
| mob_tp_25  |     22    |
+------------+-----------+

= electricity =
+-----+-------+
|  id | name  |
+-----+-------+
|  25 | test1 |
|  11 | test2 |
| x73 | test3 |
+-----+-------+

  == mobile ==
+-----+----------+
|  id |   name   |
+-----+----------+
| x93 | test 66  |
| t55 | test 222 |
| 25  | test 323 |
+-----+----------+

我要选择的主表是库存表,库存表通过code列连接到另一个表,对于电力表有一个el_pr_前缀后跟电力表的id而对于移动表前缀是mob_tp_是前缀,我想从电力和移动表中选择名称列的库存表,例如结果将是这样的:

SELECT code,total, ... as name FROM inventory; 


         === inventory ===
+------------+-----------+----------+
|    code    |   total   |  name    |
+------------+-----------+----------+
| el_pr_25   |     45    | test1    |
| el_pr_11   |     33    | test2    |
| mob_tp_x93 |     23    | test 66  |
| mob_tp_t55 |     33    | test 22  |
| el_pr_x73  |     25    | test3    |
| mob_tp_25  |     22    | test 323 |
+------------+-----------+----------+

【问题讨论】:

  • 您应该尝试自己的查询,如果遇到困难,请要求我们提供帮助。您尝试使用什么查询? (请将其添加到问题中,不要对此使用评论)。

标签: mysql sql if-statement select


【解决方案1】:

我们可以试试下面的连接查询:

SELECT
    i.code,
    i.total,
    COALESCE(e.name, m.name) AS name
FROM inventory i
LEFT JOIN electricity e
    ON i.code REGEXP CONCAT('el_.*_', e.id, '$')
LEFT JOIN mobile m
    ON i.code REGEXP CONCAT('mob_.*', m.id, '$');

Demo

上述查询使用COALESCE 技巧为每个项目选择正确的名称,它假定给定项目仅匹配electricitymobile 表。

但是,您的数据库设计并不理想。最好只有一个包含移动和电气(和其他)项目元数据的表。此外,您的表应该有适当的连接列,不需要需要复杂的子字符串或正则表达式操作来匹配。我建议如下:

inventory
+----+------------+-----------+
| id |    code    |   total   |
+----+------------+-----------+
| 1  | el_pr_25   |     45    |
| 2  | el_pr_11   |     33    |
| 3  | el_pr_x73  |     25    |
| 4  | mob_tp_x93 |     23    |
| 5  | mob_tp_t55 |     33    |
| 6  | mob_tp_25  |     22    |
+----+------------+-----------+

items
+--------------+----------+-------------+
| inventory_id | name     | type        |
+--------------+----------+-------------+
| 1            | test1    | electricity |
| 2            | test2    | electricity |
| 3            | test3    | electricity |
| 4            | test 66  | mobile      |
| 5            | test 222 | mobile      |
| 6            | test 323 | mobile      |
+--------------+----------+-------------+

【讨论】:

  • 你觉得这个数据模型没问题吗?
  • @Used_By_Already 是的,数据库设计并不理想,我会对此添加评论。
  • @TimBiegeleisen 是的,我知道,我刚从上级那里收到数据库
  • @blue 为了您自己的信息,作为建议,我提供了一个建议,说明您如何更好地构建表数据。只需使用数字作为库存键,如果您只有一个执行相同操作的逻辑表,请不要到处创建表。
【解决方案2】:

您可以使用inner joinunion [all] 作为:

select i.*, e.name from inventory i 
                   inner join electricity e on ( i.code = concat('el_pr_',e.id) ) union all
select i.*, m.name from inventory i 
                   inner join mobile m on ( i.code = concat('mob_tp_',m.id) );

Rextester Demo

【讨论】:

    【解决方案3】:

    我建议将您的数据模型更改为单独的列,并通过同时使用它们形成独特的约束。

    |code  |   total   |type
    +------+-----------+
    | 25   |     45    |el_pr_
    | 11   |     33    |el_pr_
    | x93  |     23    |mob_tp_
    | t55  |     33    |mob_tp_
    | x73  |     25    |el_pr_
    | 25   |     22    |mob_tp_
    

    并将名称来源合并到一个表中

    |  id | name  |type
    +-----+-------+
    |  25 | test1 |el_pr_
    |  11 | test2 |el_pr_
    | x73 | test3 |el_pr_
    | x93 | test 66  |mob_tp_
    | t55 | test 222 |mob_tp_
    | 25  | test 323 |mob_tp_
    

    然后

    select *
    from inventory i
    join tab_names n on i.type = n.type and i.code = n.id
    

    这只是一个粗略的轮廓!

    【讨论】:

    • 我不知道为什么这被否决 +1。不是直接的答案,但无论如何这是一个很好的建议。
    猜你喜欢
    • 1970-01-01
    • 2015-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-29
    • 1970-01-01
    • 1970-01-01
    • 2022-01-22
    相关资源
    最近更新 更多