【问题标题】:Select columns that are not null in any record选择任何记录中不为空的列
【发布时间】:2014-07-09 15:35:06
【问题描述】:

我需要分析一个 MySQL 表,并希望确定该表中任何记录中从不包含 NULL、0 或空字符串的所有。 我不知道该怎么做,因为 MySQL 希望我选择语句开头的列。我想我可以将桌子旋转 90°,然后做类似的事情

SELECT column_header FROM rotated_table WHERE record_1 <> NULL AND record_2 <> NULL AND [...]

但这似乎需要做很多工作。 有没有更简单的方法来获取我需要的信息?

更新示例

表1:

name        street      zip
MyName      1st Ave.    1000
OtherName   2nd Street  NULL

我的陈述现在应该显示如下:

name        street
MyName      1st Ave.
OtherName   2nd Street

因为列 zip 包含 NULL 值。 如果有一个额外的行像

name        street      zip
MyName      1st Ave.    1000
OtherName   2nd Street  NULL
NULL        Foo blvd.   3453

它应该返回

street
1st Ave.
2nd Street
Foo blvd.

因为 namezip 至少包含一个 NULL 值。

【问题讨论】:

    标签: mysql sql select dynamic-columns


    【解决方案1】:

    您可以利用 COUNT 忽略 NULL 值的行为对您有利。

    从行数中减去您正在检查的列数。返回值0 的任何列都不包含NULL 值。您需要使用CASE 语句将您认为“空”的任何值转换为NULL

    这种方法还消除了复制整个表格以“旋转”它的需要。

    我创建了一个示例 here in SQLFiddle,它应该对你有用。

    这里是my SQLFiddle example的内容,以防链接失效:

    CREATE TABLE address
    (
        address int auto_increment primary key, 
        street1 varchar(20),
        street2 varchar(20),
        city varchar(20),
        state varchar(20),
        zip int,
        comment varchar(20)
    );
    
    INSERT INTO address
    (street1, street2, city, state, zip, comment)
    VALUES
    ('123 Main St.', null, 'Cleveland', 'OH', 44123, ''),
    ('1313 Mockingbird Ln.', null, 'Cleveland', 'OH', 0, 'Unknown zip'),
    ('321 Main St.', 'Apt #1', 'Cleveland', 'OH', 44123, ''),
    ('321 Main St.', 'Apt #2', 'Cleveland', 'OH', 44123, '');
    
    SELECT
    COUNT(*) rows, -- not really needed, you can remove this
    COUNT(*) - COUNT(CASE ad.street1 WHEN '' THEN NULL ELSE ad.street1 END) empty_street1,
    COUNT(*) - COUNT(CASE ad.street2 WHEN '' THEN NULL ELSE ad.street2 END) empty_street2,
    COUNT(*) - COUNT(CASE ad.city WHEN '' THEN NULL ELSE ad.city END) empty_city,
    COUNT(*) - COUNT(CASE ad.state WHEN '' THEN NULL ELSE ad.state END) empty_state,
    -- Change the value being compared based on the column type.  Strings '', numbers 0, etc.
    COUNT(*) - COUNT(CASE ad.zip WHEN 0 THEN NULL ELSE ad.zip END) empty_zip,
    COUNT(*) - COUNT(CASE ad.comment WHEN '' THEN NULL ELSE ad.comment END) empty_comment
    FROM address ad;
    

    结果:

    ROWS    EMPTY_STREET1   EMPTY_STREET2   EMPTY_CITY  EMPTY_STATE     EMPTY_ZIP   EMPTY_COMMENT
    4       0               2               0           0               1           3
    

    【讨论】:

    • 呸 - 我不知何故错过了 0 和空字符串要求。我会尽快修改。
    • 给你 - 我相信这应该符合你的要求。
    • 现在使用count(*),因为它总是计算所有记录。
    • 谢谢。这几乎是我想要的:如果它们返回0,现在是否还有可能排除列的显示?这实际上是我的关键方面。
    • 如果我理解您的要求,那么对于我上面的示例,您只想显示EMPTY_STREET2EMPTY_ZIPEMPTY_COMMENT
    【解决方案2】:

    NULL 的正确比较是IS NULLIS NOT NULL。所以:

    SELECT column_header
    FROM rotated_table
    WHERE record_1 IS NOT NULL AND record_2 IS NOT NULL AND [...];
    

    但是,“记录”对于列来说是一个奇怪的名称。您要确保列名在 WHERE 子句中。

    【讨论】:

    • 对不起,我完全混淆了问题中的列和行。这实际上是关于只选择在任何行中永远不会为空的
    • @RichardNeumann 。 . .我建议您删除此问题并提出另一个问题。包括样本数据和您想要的结果。
    猜你喜欢
    • 2020-02-13
    • 2016-04-19
    • 1970-01-01
    • 1970-01-01
    • 2012-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-19
    相关资源
    最近更新 更多