在 MySQL 中,我有一个由 300 多列组成的表,我必须仅提取至少在一行中具有值(不为空)的列。
其他类似问题的一些答案表明我们可以使用存储过程来仅选择不可为空的列。这不代表需求。
该表正在处理事务,我不想手动扫描每一列和行,只是想弄清楚我们如何使用 SQL (MySQL) 动态地实现。
使用存储过程但执行失败的示例:
CREATE PROCEDURE hrdc_ace_dl.find_aps()
begin
SET @sql = NULL;
SELECT
GROUP_CONCAT(distinct
CONCAT(
'SELECT ', COLUMN_NAME, ' AS column_name FROM aps_transaction WHERE ', COLUMN_NAME, ' IS NOT NULL LIMIT 1'
) SEPARATOR ' UNION ALL ')
INTO @sql
FROM
information_schema.columns
WHERE
table_schema = 'hrdc_ace_dl'
AND table_name = 'aps_transaction';
SET @sql = CONCAT('SELECT column_name FROM (', @sql, ') AS tmp_table');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END
除了使用
LIMIT
和 UNION ALL
函数问题之外,还有另一部分您必须添加以将 COLUMN_NAME
返回为“列名称”。我的意思是这样的;下面是添加括号的查询,用于解决 limit+union all
问题:
SELECT
GROUP_CONCAT(distinct
CONCAT( /* this part here */
/*added opening parenthesis --->*/ '(SELECT ', COLUMN_NAME, ' AS column_name
FROM aps_transaction WHERE ', COLUMN_NAME, ' IS NOT NULL LIMIT 1)'/*<--- added closing parenthesis*/
) SEPARATOR ' UNION ALL ')
INTO @sql
FROM
information_schema.columns
WHERE
table_schema = 'hrdc_ace_dl'
AND table_name = 'aps_transaction';
连接的
COLUMN_NAME
中的当前 SELECT
将返回与 1
等效的 true
。因此,如果您想返回确切的列名称,只需将其用引号括起来,如 "', COLUMN_NAME, '"
。