【问题标题】:MySQL Join tables with virtual columnsMySQL 使用虚拟列连接表
【发布时间】:2016-10-08 00:51:51
【问题描述】:

我想创建虚拟列。在list id 主表中,我需要使用“数据”连接虚拟列。

Table: columns
+------+---------+-------------+
| [ID] | ID_USER |   DATENAME  |
+------+---------+-------------+
|   1  |   NULL  | Description |
+------+---------+-------------+
|   2  |   NULL  |     Cost    |
+------+---------+-------------+
|   3  |    2    |    Width    |
+------+---------+-------------+

Table: list
+----+-----------+------------+--------+
|[ID]|    NAME   |    DATE    |  COLOR |
+----+-----------+------------+--------+
|  1 |  234/2016 | 2016-06-06 |   red  |
+----+-----------+------------+--------+
|  2 | 1000/2016 | 2016-06-07 |  blue  |
+----+-----------+------------+--------+
|  3 | 3456/2016 | 2016-06-08 | yellow |
+----+-----------+------------+--------+


Table: data
+-----------+-----------+-------+
| ID_REPAIR | ID_COLUMN | VALUE |
+-----------+-----------+-------+
|     1     |     1     |  aaaa |
+-----------+-----------+-------+
|     1     |     2     |  10$  |
+-----------+-----------+-------+
|     2     |     1     |  bbbb |
+-----------+-----------+-------+
|     2     |     2     |  20$  |
+-----------+-----------+-------+
|     3     |     1     |  cccc |
+-----------+-----------+-------+
|     3     |     2     |  30$  |
+-----------+-----------+-------+


Result:
+------+-----------+------------+--------+-------------+------+
| [ID] |    NAME   |    DATE    |  COLOR | Description | Cost |
+------+-----------+------------+--------+-------------+------+
|   1  |  234/2016 | 2016-06-06 |   red  |     aaaa    |  10$ |
+------+-----------+------------+--------+-------------+------+
|   2  | 1000/2016 | 2016-06-07 |  blue  |     bbbb    |  20$ |
+------+-----------+------------+--------+-------------+------+
|   3  | 3456/2016 | 2016-06-08 | yellow |     cccc    |  30$ |
+------+-----------+------------+--------+-------------+------+

在这个查询中我得到名字columns:

SELECT * FROM `columns` WHERE `id_user` IS NULL

在 PHP 中将 ID 保存到变量中,但在测试中我想生成只有第二列的表。在下面的代码中,我想用Cost 列生成结果,但总是插入Description 列:

SQL:

SELECT `list`.`id`, `name`, `date`, `color`, `data`.`value`
FROM `list` 
INNER JOIN `data` ON `list`.`id` = `data`.`id_repair` WHERE `repair_data`.`id_column` = 2

我不知道如何只在 id_column 等于 2 时进行 INNER JOIN

【问题讨论】:

    标签: mysql sql dynamic multiple-columns


    【解决方案1】:

    SELECT 返回的列数不能在执行时动态确定。必须在查询的SELECT 列表中指定列数以及分配给每列的数据类型和名称(或别名)。所以让我们开始吧。

    要让 SQL 语句返回所示的结果集,查询需要采用以下形式:

     SELECT l.id
          , l.name
          , l.date
          , l.color
          , (expr1)     AS `Description`
          , (expr2)     AS `Cost`
       FROM list l
        ... 
    

    返回 列。

    至于表达式 expr1expr2 您将使用返回 DescriptionCost 列,有几种方法可以将实体属性值 (EAV) 模型展开回规范关系模型。

    最容易理解但不一定是最好的选择是在 SELECT 列表中使用相关子查询。举个例子:

     SELECT l.id
          , l.name
          , l.date
          , l.color
          , ( SELECT d.value
                FROM `data` d
               WHERE d.id_repair = l.id
                 AND d.id_column = 1
               ORDER BY d.value
               LIMIT 1
            )                      AS `Description`
          , ( SELECT c.value
                FROM `data` c
               WHERE c.id_repair = l.id
                 AND c.id_column = 2
               ORDER BY c.value
               LIMIT 1
            )                      AS `Cost`
          , ( SELECT w.value
                FROM `data` w
               WHERE w.id_repair = l.id
                 AND w.id_column = 3
               ORDER BY w.value
               LIMIT 1
            )                      AS `Width`
       FROM list l
      ORDER BY l.id
    

    请注意,SELECT 列表中的相关子查询只能返回一行,并返回单个表达式。也就是说,它返回一个单个值。


    作为替代方案,我们可以使用外连接操作和条件聚合。例如:

     SELECT l.id
          , l.name
          , l.date
          , l.color
          , MAX(IF(d.id_column=1,d.value,NULL)) AS `Description`
          , MAX(IF(d.id_column=2,d.value,NULL)) AS `Cost`
          , MAX(IF(d.id_column=3,d.value,NULL)) AS `Width`
       FROM list l
       LEFT
       JOIN data d
         ON d.id_repair = l.id 
      GROUP BY l.id, l.name, l.date, l.color
    

    如果我们需要根据存储在数据库表中的信息,使返回的结果动态,具有不同数量的列和用于列的表达式,那么我们可以首先获取来自数据库的信息,然后使用它来帮助我们构建我们需要执行的实际 SQL 语句以获得最终结果。

    或者,正如许多使用实体属性值 (EAV) 模型的应用程序所做的那样,我们甚至不会尝试将 EAV 模型强制转换为规范的关系模型。我们只是让应用程序运行从表中检索信息所需的多个查询。基本上与应用程序向表中插入行的方式相反。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-25
      • 1970-01-01
      • 2013-02-18
      • 1970-01-01
      • 2020-07-30
      • 1970-01-01
      • 1970-01-01
      • 2018-01-22
      相关资源
      最近更新 更多