【问题标题】:SQLite SELECT row WHERE number of fields not equal to null falls within a rangeSQLite SELECT 行 WHERE 不等于 null 的字段数在一个范围内
【发布时间】:2020-04-21 19:04:00
【问题描述】:

我正在尝试将数据集分组为可管理的块。为了优先考虑首先关注哪些记录,我想将记录分组为“完整性”级别的块,其中完整性 == 给定行中不等于 null 的列数。我在逻辑上遇到问题,只返回具有一定数量列的行不等于 null。

例如,如果我有一个包含 10 列和 10 行的表。

  1. 组 1 将包含给定行的不等于 null 的列数大于或等于 8 的所有行。 即)不为空>=8

  2. 组 2 将包含给定行的不等于 null 的列数大于或等于 6 且小于 8 的所有行。 即)不为空>=6且不为空

  3. 第 3 组将包含给定行的不等于 null 的列数大于或等于 4 且小于 6 的所有行。

  4. 等等。

我下面的查询是最接近的尝试,但它显然被破坏了,我不确定如何循环遍历每一列并让Logic 每次增加 1,而不是仅用 1 或 0 替换单个值. 这样做最好吗?我在哪里循环并根据 NULL 列的数量增加新列中的值,然后仅根据该值进行过滤?

或者,理想情况下,我可以只返回不等于 null 的列数在给定范围内的行。但我不确定这在 SQLite 中是否可行。

SELECT *
CASE WHEN * IS NOT NULL
    THEN 1
    ELSE 0
    END AS Logic
FROM contacts_all
WHERE Logic >=8;

这在 SQLite 中可行吗?我尝试在 Python 中做到这一点很好,但是数据集非常庞大,以至于每次都会使我的计算机崩溃。坦率地说,可能是因为我的 python 代码很垃圾。

任何反馈或想法都将非常有价值和感激,谢谢!

编辑:还值得一提的是,任何涉及输入每列名称的解决方案都不理想(尽管很感激!)因为列数是 247。我希望避免输入每个名称进入查询。虽然我可以在 Excel 中进行 CONCAT 格式化,但我很想学习如何在 SQL 中实际执行此操作。

EDIT2:这是一个示例表和所需的结果:

+---------+---------+---------+------+
|  Col1   |  Col2   |  Col3   | Col4 |
+---------+---------+---------+------+
| Value 1 | Value 2 | Value 3 | NULL |
| Banana  | 123     | NULL    | NULL |
| Banana  | 123     | NULL    | NULL |
| Banana  | NULL    | NULL    | NULL |
+---------+---------+---------+------+

第 1 组:WHERE 字段数不等于 null >= 3 返回第 1 行

第 2 组:WHERE 字段数不等于 null =2 返回第 1、2、3 行

第 3 组:WHERE 字段数不等于 null = 1 返回第 1、2、3、4 行

【问题讨论】:

  • 样本数据和期望的结果会有所帮助。
  • 对于这个要求,一个有 247 列的表是一个糟糕的设计。

标签: python sql sqlite


【解决方案1】:

你可以这样应用你的条件:

SELECT *
FROM contacts_all
WHERE 
  (col1 IS NOT NULL) + (col2 IS NOT NULL) + (col3 IS NOT NULL) + (col4 IS NOT NULL) + (col5 IS NOT NULL) + 
  (col6 IS NOT NULL) + (col7 IS NOT NULL) + (col8 IS NOT NULL) + (col9 IS NOT NULL) + (col10 IS NOT NULL) >= 8

对于TRUE,每个条件(colX IS NOT NULL) 的计算结果为1,对于FALSE,则为0
您可以使用 BETWEEN 6 AND 7 代替 >= 8 或任何其他有效的运算符。
或者使用CTE,您将在其中计算非空列的数量:

WITH cte AS (
  SELECT *,
    (col1 IS NOT NULL) + (col2 IS NOT NULL) + (col3 IS NOT NULL) + (col4 IS NOT NULL) + (col5 IS NOT NULL) + 
    (col6 IS NOT NULL) + (col7 IS NOT NULL) + (col8 IS NOT NULL) + (col9 IS NOT NULL) + (col10 IS NOT NULL) AS Logic
  FROM contacts_all
)
SELECT * FROM cte
WHERE Logic >= 8

【讨论】:

    猜你喜欢
    • 2018-01-19
    • 2017-06-15
    • 2016-09-30
    • 1970-01-01
    • 2011-12-30
    • 1970-01-01
    • 2015-12-22
    • 1970-01-01
    • 2011-05-12
    相关资源
    最近更新 更多