我在mysql中有一个有80列的表。这些列中的大多数都没有值null。通常,每行返回大约8或9个非空列(数据已插入(。我相信在mysql语句中,不可能从提取的行中只返回不为null的列。我的问题是,作为Python的初学者,在这个脚本中实现我的目标的最佳方法是什么?更好地解释如下:
- mysql查询获取一行
- 该行有8个非空列
- 该行有72个空列
- 如果第一列不为null,则显示列名和列数据
- 如果第二列不为null,则显示列名和列数据6如果第三列不是。。。。。。。。依此类推,直到最后一列
感谢您在这方面的帮助。
输出列表必须是确定的,即其中的列数不能是动态的。例如,您可以决定输出将包含10列,并根据查询进行创建。
图案:
SELECT id,
CASE WHEN cnt > 0
THEN SUBSTRING_INDEX(SUBSTRING_INDEX(total, CHAR(0), 1), CHAR(0), -1)
END field1,
CASE WHEN cnt > 1
THEN SUBSTRING_INDEX(SUBSTRING_INDEX(total, CHAR(0), 2), CHAR(0), -1)
END field2,
..
CASE WHEN cnt > 9
THEN SUBSTRING_INDEX(SUBSTRING_INDEX(total, CHAR(0), 10), CHAR(0), -1)
END field10,
cnt
FROM ( SELECT id,
CONCAT_WS(CHAR(0), field1, field2, .. , field80) total,
field1 IS NOT NULL + field2 IS NOT NULL + .. + field80 IS NOT NULL cnt
FROM source_table ) AS compacted
这个想法很简单——CONCAT_WS跳过NULL值。CHAR(0(被用作分隔符,因为它是任何非二进制数据类型的值中最罕见的字符。
如果NOT NULL值的数量低于10,则其余输出值将为NULL。
如果NOT NULL值的数量超过10,则不会显示其余值。这可以通过cnt
列值而不是80个BIT列来检测。
但您的值仅为0
或1
,因此您可以简化查询直到
SELECT id,
SUBSTRING(total FROM 1 FOR 1) field1,
SUBSTRING(total FROM 2 FOR 1) field2,
...
SUBSTRING(total FROM 10 FOR 1) field10,
cnt
FROM ( SELECT id,
CONCAT_WS('', field1, field2, .. , field80) total,
field1 IS NOT NULL + field2 IS NOT NULL + .. + field80 IS NOT NULL cnt
FROM source_table ) AS compacted
不同的是,对于多余的列,此查询将返回空字符串,而不是NULL值。如果需要NULL,则应用NULLIF((函数。
但我强烈建议您将数据标准化。请使用EAV模式或至少2列SET数据类型。