【问题标题】:Include null values in sqlite result [duplicate]在 sqlite 结果中包含空值 [重复]
【发布时间】:2019-05-11 17:15:27
【问题描述】:

您好 sqlite3 专家,

我有一个名为 positionlogs 的表,其结构如下:

id | positionId | scanTime
 1 |          1 | 2019-05-11 14:18:58.802 +00:00
 2 |          2 | 2019-05-11 14:24:05.518 +00:00
 3 |          1 | 2019-05-11 14:34:01.777 +00:00
 4 |          1 | 2019-05-11 14:34:02.549 +00:00
 5 |          1 | 2019-05-11 14:34:06.560 +00:00
 6 |          1 | 2019-05-11 14:34:07.484 +00:00

然后我执行以下查询:

SELECT ranges.start, 
       ranges.end,
       count(positionLogs.id) as totalScans
 FROM 
 (
  SELECT strftime('%Y-%m-%d %H:%M', '2019-05-11 14:35','-55 minutes') as start, strftime('%Y-%m-%d %H:%M', '2019-05-11 14:35','-50 minutes') as end UNION ALL
  SELECT strftime('%Y-%m-%d %H:%M', '2019-05-11 14:35','-50 minutes') as start, strftime('%Y-%m-%d %H:%M', '2019-05-11 14:35','-45 minutes') as end UNION ALL
  SELECT strftime('%Y-%m-%d %H:%M', '2019-05-11 14:35','-45 minutes') as start, strftime('%Y-%m-%d %H:%M', '2019-05-11 14:35','-40 minutes') as end UNION ALL
  SELECT strftime('%Y-%m-%d %H:%M', '2019-05-11 14:35','-40 minutes') as start, strftime('%Y-%m-%d %H:%M', '2019-05-11 14:35','-35 minutes') as end UNION ALL
  SELECT strftime('%Y-%m-%d %H:%M', '2019-05-11 14:35','-35 minutes') as start, strftime('%Y-%m-%d %H:%M', '2019-05-11 14:35','-30 minutes') as end UNION ALL
  SELECT strftime('%Y-%m-%d %H:%M', '2019-05-11 14:35','-30 minutes') as start, strftime('%Y-%m-%d %H:%M', '2019-05-11 14:35','-25 minutes') as end UNION ALL
  SELECT strftime('%Y-%m-%d %H:%M', '2019-05-11 14:35','-25 minutes') as start, strftime('%Y-%m-%d %H:%M', '2019-05-11 14:35','-20 minutes') as end UNION ALL
  SELECT strftime('%Y-%m-%d %H:%M', '2019-05-11 14:35','-20 minutes') as start, strftime('%Y-%m-%d %H:%M', '2019-05-11 14:35','-15 minutes') as end UNION ALL
  SELECT strftime('%Y-%m-%d %H:%M', '2019-05-11 14:35','-15 minutes') as start, strftime('%Y-%m-%d %H:%M', '2019-05-11 14:35','-10 minutes') as end UNION ALL
  SELECT strftime('%Y-%m-%d %H:%M', '2019-05-11 14:35','-10 minutes') as start, strftime('%Y-%m-%d %H:%M', '2019-05-11 14:35','-5 minutes') as end UNION ALL
  SELECT strftime('%Y-%m-%d %H:%M', '2019-05-11 14:35','-5 minutes') as start, strftime('%Y-%m-%d %H:%M', '2019-05-11 14:35','-0 minutes') as end) as ranges
  LEFT join positionlogs on (positionlogs.scanTime >= ranges.start AND positionlogs.scanTime <=ranges.end)
   where positionlogs.positionId = 1
   group by start;

我想要实现的是获得类似于以下的结果:

start            | end                | totalScans
2019-05-11 13:40 | 2019-05-11 13:45   | 0
2019-05-11 13:45 | 2019-05-11 13:50   | 0
2019-05-11 13:50 | 2019-05-11 13:55   | 0
2019-05-11 13:55 | 2019-05-11 14:00   | 0
2019-05-11 14:00 | 2019-05-11 14:05   | 0
2019-05-11 14:05 | 2019-05-11 14:10   | 0
2019-05-11 14:10 | 2019-05-11 14:15   | 0
2019-05-11 14:15 | 2019-05-11 14:20   | 1
2019-05-11 14:20 | 2019-05-11 14:25   | 1
2019-05-11 14:25 | 2019-05-11 14:30   | 4
2019-05-11 14:30 | 2019-05-11 14:35   | 0

但我的查询不是这样返回的:

start            | end                | totalScans
2019-05-11 14:15 | 2019-05-11 14:20   | 1
2019-05-11 14:20 | 2019-05-11 14:25   | 1
2019-05-11 14:25 | 2019-05-11 14:30   | 4

我尝试了几种不同的方法,但都没有成功。 非常感谢任何帮助/建议!

【问题讨论】:

  • 请用文字解释结果如何是输入的函数。否则,我们必须尝试从您的一个示例中猜测。请在代码问题中提供minimal reproducible example--cut & paste & runnable code;具有期望和实际输出的示例输入(包括逐字错误消息);明确的规范和解释。这包括您可以提供的最少代码,即您显示的代码可以通过您显示的代码扩展为不可以。 (调试基础。)PS“最小”
  • 这是一个常见问题解答。在考虑发布之前,请始终在谷歌上搜索您的错误消息或您的问题/问题/目标的许多清晰、简洁和精确的措辞,有或没有您的特定字符串/名称,并阅读许多答案。如果您发布问题,请使用一个短语作为标题。请参阅How to Ask 和投票箭头鼠标悬停文本。
  • 了解 LEFT JOIN ON 返回的内容:INNER JOIN ON 行 UNION ALL 不匹配的左表行,由 NULL 扩展。作为 OUTER JOIN 的一部分,始终知道您想要什么 INNER JOIN。 WHERE 或 INNER JOIN ON 在 OUTER JOIN ON 删除任何由 NULL 扩展的行后,需要右 [sic] 表列不为 NULL,即只留下 INNER JOIN ON 行,即“将 OUTER JOIN 转换为 INNER JOIN”。你有那个。
  • 您的标题显示“在 sqlite 结果中包含空值”,但您的查询既不保留也不计算从左连接获取空值的列中的空值。研究计数(列)与计数(*)。

标签: sql sqlite join null


【解决方案1】:

好吧,您离开了 join positionlogs,但随后有一个 WHERE 子句希望 positionlogs.positionid 成为 1。来自ranges 的行(其中未找到来自postionlog 的匹配行)不能满足此要求,因此被过滤掉。将表达式从 WHERE 移动到 ON 子句以解决此问题。

SELECT ranges.start, 
       ...
       ... ranges
       LEFT JOIN positionlogs
                 ON positionlogs.scanTime >= ranges.start
                    AND positionlogs.scanTime <=ranges.end
                    AND positionlogs.positionId = 1
       GROUP BY ranges.start;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    • 2015-07-19
    • 1970-01-01
    相关资源
    最近更新 更多