仅展示非NULL数据:基于users与user_points表的用户选项需求
解决方案:展示两张表中的非NULL数据
首先,我们需要将users和user_points表通过用户唯一标识关联起来(users.uid = user_points.user_id),然后过滤掉所有值为NULL的字段内容。这里提供两种常见的实现方式,根据你的展示需求选择:
方式1:保留表结构,仅显示非空值
如果希望保持原有表的列结构,但只填充非空数据,可以使用LEFT JOIN关联两张表,查询时直接选取所有字段,数据库会自动忽略NULL值(对应位置显示为空):
SELECT u.id AS user_table_id, u.uid, u.fname, u.lname, u.pic, up.id AS points_table_id, up.opt1, up.opt2, up.opt3, up.opt4, up.opt5, up.opt6 FROM users u LEFT JOIN user_points up ON u.uid = up.user_id;
这个查询会返回所有用户的信息:对于没有对应积分数据的用户(比如Vicky),积分相关的列会显示为空;而有积分数据的用户,只有非空的opt字段会展示数值。
方式2:转换为键值对格式,直观展示所有非空内容
如果希望彻底避免空列,把所有非空的数据以「字段名-值」的形式展示,可以使用UNION ALL来展开所有非空字段:
-- 提取users表中的非空数据 SELECT u.uid, 'fname' AS field_name, u.fname AS field_value FROM users u WHERE u.fname IS NOT NULL UNION ALL SELECT u.uid, 'lname' AS field_name, u.lname AS field_value FROM users u WHERE u.lname IS NOT NULL UNION ALL SELECT u.uid, 'pic' AS field_name, u.pic AS field_value FROM users u WHERE u.pic IS NOT NULL -- 提取user_points表中的非空数据 UNION ALL SELECT up.user_id AS uid, 'opt1' AS field_name, CAST(up.opt1 AS VARCHAR) AS field_value FROM user_points up WHERE up.opt1 IS NOT NULL UNION ALL SELECT up.user_id AS uid, 'opt2' AS field_name, CAST(up.opt2 AS VARCHAR) AS field_value FROM user_points up WHERE up.opt2 IS NOT NULL UNION ALL SELECT up.user_id AS uid, 'opt3' AS field_name, CAST(up.opt3 AS VARCHAR) AS field_value FROM user_points up WHERE up.opt3 IS NOT NULL UNION ALL SELECT up.user_id AS uid, 'opt4' AS field_name, CAST(up.opt4 AS VARCHAR) AS field_value FROM user_points up WHERE up.opt4 IS NOT NULL UNION ALL SELECT up.user_id AS uid, 'opt5' AS field_name, CAST(up.opt5 AS VARCHAR) AS field_value FROM user_points up WHERE up.opt5 IS NOT NULL UNION ALL SELECT up.user_id AS uid, 'opt6' AS field_name, CAST(up.opt6 AS VARCHAR) AS field_value FROM user_points up WHERE up.opt6 IS NOT NULL ORDER BY uid;
这个查询会把所有非空数据拆分成每行一条记录,比如uid为5TQ4G1的用户会返回以下内容:
5TQ4G1 | fname | Zen
5TQ4G1 | lname | D
5TQ4G1 | pic | img1.png
5TQ4G1 | opt1 | 20
5TQ4G1 | opt2 | 30
5TQ4G1 | opt3 | 60
注意事项
- 如果你的数据库中NULL值是以空字符串(
'')存储的,需要把IS NOT NULL替换为<> ''来过滤。 - 方式2中需要把数值类型的opt字段转换为字符串(
CAST(...)),确保UNION ALL时字段类型一致。
内容的提问来源于stack exchange,提问作者meenal
相关产品推荐
相关产品推荐

