如何在获取的 mysql 行中仅显示非空列?
How to display only not null columns in a fetched mysql row?
我在 mysql 中有一个包含 80 列的 table。这些列中的大多数都没有值,为空。通常,每行 return 大约有 8 或 9 列不为空(已插入数据)。我相信在 mysql 语句中没有办法从获取的行中 return 只有不为空的列。我的问题是,由于我是 Python 的初学者,该脚本中实现我的目标的最佳方法是什么?更好地解释如下:
- 一个 mysql 查询获取了一行
- 该行有 8 个非空列
- 该行有 72 个空列
- 如果第一列不为空则显示列名和列数据
- 如果第二列不为空则显示列名和列数据
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
区别 - 对于多余的列,此查询将 return 空字符串,而不是 NULL 值。如果您需要 NULL,则应用 NULLIF() 函数。
但我强烈建议您规范化数据。使用 EAV 模式或至少 2 列 SET 数据类型。
我在 mysql 中有一个包含 80 列的 table。这些列中的大多数都没有值,为空。通常,每行 return 大约有 8 或 9 列不为空(已插入数据)。我相信在 mysql 语句中没有办法从获取的行中 return 只有不为空的列。我的问题是,由于我是 Python 的初学者,该脚本中实现我的目标的最佳方法是什么?更好地解释如下:
- 一个 mysql 查询获取了一行
- 该行有 8 个非空列
- 该行有 72 个空列
- 如果第一列不为空则显示列名和列数据
- 如果第二列不为空则显示列名和列数据 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
区别 - 对于多余的列,此查询将 return 空字符串,而不是 NULL 值。如果您需要 NULL,则应用 NULLIF() 函数。
但我强烈建议您规范化数据。使用 EAV 模式或至少 2 列 SET 数据类型。