MySQL:如何转移未知的名称 - 值对?

时间:2011-04-03 03:11:26

标签: mysql sql database

说我有以下内容:

-------------------------------------
| id | user_id | name       | value |
=====================================
| 1  | 10      | First Name | John  |
-------------------------------------
| 1  | 10      | Last Name  | Doe   |
-------------------------------------
| 1  | 10      | Age        | 25    |
-------------------------------------

假设我不知道“名字”,“姓氏”和“年龄”是表格name列中的值。我如何查询这个表,所以我得到这样的东西:

------------------------------------------
| user_id | First Name | Last Name | Age |
==========================================
| 10      | John       | Doe       | 25  |
------------------------------------------

1 个答案:

答案 0 :(得分:1)

Mysql没有内置的方法来解决这个问题,我很清楚。你需要创建一些逻辑。我相信你必须创建一个存储过程,或者在你的应用程序代码中编写一些逻辑来执行以下操作:

  1. 查询所有不同的“名称”字段
  2. http://en.wikibooks.org/wiki/MySQL/Pivot_table
  3. 所述动态创建并执行包含所有字段的查询

    如果你想在mysql端完全这样做,你可以在http://www.java2s.com/Code/SQL/Procedure-Function/EXECUTEdynamicSQLcommand.htm中描述的存储过程中使用动态sql。

    这是一个适合你的程序:

    DROP PROCEDURE myProc;
    delimiter $$
    CREATE PROCEDURE myProc ()
    BEGIN
        DECLARE this_name varchar(20);
        DECLARE done INT DEFAULT 0;
        DECLARE cur1 CURSOR FOR SELECT distinct name FROM user_info;
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
    
        SET @sql='select user_info_1.user_id';
        OPEN cur1;
        read_loop: LOOP
            FETCH cur1 INTO this_name;
            IF  done THEN 
                LEAVE read_loop;
            END IF;
    
            SET @sql=CONCAT(@sql, ", (select value from user_info where user_info.user_id = user_info_1.user_id and user_info.name = '", this_name, "') as '", this_name, "'");
        END LOOP;
        SET @sql=CONCAT(@sql, ' from (select distinct user_id from user_info) user_info_1');
        PREPARE s1 FROM @sql;
        EXECUTE s1;
        DEALLOCATE PREPARE s1;
    END$$
    

    现在,这说,小心这个数据库结构。小心你没有过度设计问题。此外,您放弃了数据库可能为您提供的许多功能,实现独特的约束,外键等将非常困难或不可能。许多CRM工具都试图沿着这条路走下去,带来灾难性的结果,而今天它们通常只是自动更改基础表以根据需要添加新列。您可能想要考虑这种方法。