请任何人帮我解决我在mysql查询中的情况

时间:2014-12-19 09:36:38

标签: mysql sql database

我有这些数据..

+------+--------------+------------+
+  id  +  position_id + name       +
+------+--------------+------------+
+  1   +  1           + name_1     +
+  2   +  5           + name_2     +
+  3   +  2           + name_3     +
+  4   +  2           + name_4     +
+  5   +  2           + name_5     +
+  6   +  3           + name_6     +
+  7   +  4           + name_7     +
+  8   +  3           + name_8     +
+  9   +  2           + name_9     +
+------+--------------+------------+

..然后我想结果就像

+--------------+-----------+----------+----------+-----------+
+  position_id +  result1  + result2  +  result3 +  result4  +
+--------------+-----------+----------+----------+-----------+
+  1           +  name_1   +  @       +  @       +  @        +
+  2           +  name_3   +  name_4  +  name_5  +  name_9   +
+  3           +  name_6   +  name_8  +  @       +  @        +
+  4           +  name_7   +  @       +  @       +  @        +
+  5           +  name_2   +  @       +  @       +  @        +
+--------------+-----------+----------+----------+-----------+

我有一些结果数据的案例,这些数据是我学校的报告。数据结果必须是位于主要位置后的动态结果,如果结果为空,则播种@

有关更多数据或信息,您可以使用以下命令询问

1 个答案:

答案 0 :(得分:1)

如果列数固定,那么您可以执行以下操作: -

SELECT a.position_id, 
        COALESCE(MIN(a.name), '@') AS result1,
        COALESCE(MIN(b.name), '@') AS result2,
        COALESCE(MIN(c.name), '@') AS result3,
        COALESCE(MIN(d.name), '@') AS result4
FROM some_table a
LEFT OUTER JOIN some_table b ON a.position_id = b.position_id AND a.id < b.id
LEFT OUTER JOIN some_table c ON a.position_id = c.position_id AND b.id < c.id
LEFT OUTER JOIN some_table d ON a.position_id = d.position_id AND c.id < d.id
GROUP BY a.position_id

使用可变数量的列,如果没有根据列数动态创建SQL,或者使用GROUP_CONCAT做一些令人讨厌的事情,它就不可能实现。

但这不可能有效。

最好先进行查询以获取第一个结果,然后在调用脚本中对格式进行排序。

修改

一些讨厌的代码的时间,我仍然需要抛光!

第一位是存储过程。这会获得最大列数(稍微有点错误,但应该很容易通过一些努力来修复,现在可以工作)并动态构建SQL以创建具有此列数的临时表,然后填充它

DELIMITER ;;
CREATE DEFINER=CURRENT_USER PROCEDURE stored_procedure_name()
BEGIN

    DECLARE sql1 TEXT;
    DECLARE sql2 TEXT;
    DECLARE sql3 TEXT;
    SET @@group_concat_max_len = 32000;

    SELECT 
            GROUP_CONCAT(CONCAT('MIN(a', (1 + units.iCnt + 10 * tens.iCnt), '.name) AS result', (1 + units.iCnt + 10 * tens.iCnt)) ORDER BY (1 + units.iCnt + 10 * tens.iCnt)),
            GROUP_CONCAT(CONCAT('LEFT OUTER JOIN some_table a', (1 + units.iCnt + 10 * tens.iCnt), ' ON  a', (units.iCnt + 10 * tens.iCnt), '.position_id =  a', (1 + units.iCnt + 10 * tens.iCnt), '.position_id AND a', (units.iCnt + 10 * tens.iCnt), '.id <  a', (1 + units.iCnt + 10 * tens.iCnt), '.id') ORDER BY (1 + units.iCnt + 10 * tens.iCnt) SEPARATOR ' '),
            GROUP_CONCAT(CONCAT('result',(1 + units.iCnt + 10 * tens.iCnt), ' VARCHAR(255)') ORDER BY (1 + units.iCnt + 10 * tens.iCnt))
    INTO sql1, sql2, sql3
    FROM
        (
        SELECT MAX(count_name) as max_count_name
        FROM
        (
            SELECT COUNT(name) as count_name
            FROM some_table
            GROUP BY position_id
        ) sub0
    ) sub1,
    (SELECT 1 iCnt UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 0) units,
    (SELECT 1 iCnt UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 0) tens
    WHERE max_count_name >= (units.iCnt + 10 * tens.iCnt);

    DROP TEMPORARY TABLE IF EXISTS temp1;

    SET @sqlmain1 = CONCAT('CREATE TEMPORARY TABLE temp1(position_id INT, result0 VARCHAR(255), ', sql3, ')');
    PREPARE stmt FROM @sqlmain1;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;    

    SET @sqlmain2 = CONCAT('INSERT INTO temp1 SELECT a0.position_id, MIN(a0.name) AS result0,', sql1, ' FROM some_table a0 ', sql2, ' GROUP BY a0.position_id ');

    PREPARE stmt FROM @sqlmain2;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;    
END;;
DELIMITER ;

然后,您可以执行此操作,然后从生成的临时表中进行选择。请注意,两个语句必须在同一个SQL会话中完成,否则临时表将在您执行select时消失: -

CALL stored_procedure_name();
SELECT * FROM temp1

希望你能将这两者都传递给贾斯珀。