【问题标题】:Query and ordering on "key-value" table对“键值”表进行查询和排序
【发布时间】:2013-03-20 18:58:17
【问题描述】:

我有一个问题,我的 SQL 太基础了,无法克服它。
我有两张桌子:

表 1

  • id (int) - (主键)
  • 电子邮件(字符)
  • 其他字段...

表2

  • id (int) - (这不是主键也不是唯一的。这是与TABLE1.id 相关的外键)
  • 键(字符)
  • 值(字符)
  • 其他字段...

第二个表的结构是“key-value”。

对于每个TABLE1.id,我在TABLE2TABLE1.id == TABLE2.id 中有“许多”行。特别是我可以有以下情况:

TABLE1 中的一行

id = 10, email = "albert.einstein@genius.com", (other fields omitted)...

TABLE2 中的对应行

id = 10, key = "first_name", value = "Albert", (other fields omitted)...
id = 10, key = "last_name", value = "Einstein", (other fields omitted)...

我想编写一个 SQL 查询,它能够返回具有以下结构的表 TABLE3

表3

  • id (int)
  • 名字(字符)
  • 姓氏(字符)
  • 电子邮件(字符)

TABLE3 应为TABLE1 中呈现的每一行包含一行,并应按last_namefirst_name 排序

按照这个例子,我应该得到一个行类似于这个的表:

id = 10, first_name = "Albert", last_name = "Einstein", email = "albert.einstein@genius.com"

我快疯了!!!

【问题讨论】:

    标签: mysql sql pivot entity-attribute-value


    【解决方案1】:

    您需要将这些键值对透视到列中,不幸的是,MySQL 没有透视表操作符。但是您可以使用CASE 表达式来执行此操作:

    SELECT
      t1.id,
      MAX(CASE WHEN t2.key = 'first_name' THEN value END) AS first_name,
      MAX(CASE WHEN t2.key = 'last_name' THEN value END) AS last_name,
      t1.email
    FROM table1 AS t1 
    INNER JOIN table2 AS t2 ON t1.id = t2.id
    GROUP BY t1.id,
             t1.email;
    

    SQL Fiddle Demo


    如果您想动态地执行此操作而不是手动写入所有这些值,您必须使用动态 SQL 来执行此操作:

    SET @sql = NULL;
    SELECT
      GROUP_CONCAT(DISTINCT CONCAT('MAX(IF(t2.key = ''',
          t2.key, ''', t2.value, 0)) AS ', '''',   t2.key, '''')
      ) INTO @sql
    FROM table2 AS t2;
    
    SET @sql = CONCAT('
      SELECT
        t1.id,', @sql, ',
        t1.email
      FROM table1 AS t1 
      INNER JOIN table2 AS t2 ON t1.id = t2.id
      GROUP BY t1.id, t1.email');
    
    prepare stmt 
    FROM @sql;
    
    execute stmt;
    

    SQL Fiddle Demo

    【讨论】:

    • 谢谢!最后一行可能是“INNER JOIN table2 AS t2 ON t1.id = t2.id”,不是吗?
    • @the_candyman - 是的,抱歉,请参阅我的编辑。现在应该修好了。
    • 好的,我明天上班的时候试试(现在是晚上11点)
    • @the_candyman - 好的,请花点时间在这里 9:30 :) 如果您想动态地为 table2 中的每个键这样做,我用动态版本更新了我的答案。
    • 啊,一个补充。该数据库是为 wordpress 网站创建的,因此所有查询都是通过 php 执行的。
    猜你喜欢
    • 2012-07-02
    • 1970-01-01
    • 2011-10-31
    • 1970-01-01
    • 2020-01-06
    • 2012-06-07
    • 2011-07-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多