我有这个数据。
+------+--------------+------------+ + 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 + @ + @ + @ + +--------------+-----------+----------+----------+-----------+
我有一些结果数据的案例,这些数据是我的学校报告的。数据结果 必须是动态的,跟随位置的主要位置 ,如果结果 为空,则播种@ 。
有关更多数据或信息,您可以使用以下命令询问
如果列数固定,则可以执行以下操作:
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
希望您可以将两者都传递给Jasper。