【问题标题】:Grabbing data between multiple date ranges in a single query在单个查询中获取多个日期范围之间的数据
【发布时间】:2016-10-30 00:58:19
【问题描述】:

我经常需要从实时数据库中获取数据,其中数据介于产品的两个日期之间。如果我在不同的日期范围内一遍又一遍地获取同一产品的数据并且必须在 Excel 工作表之间来回切换,这将非常单调。如何将日期范围合并到一个查询中,以便在 Excel 中减轻我的工作量?

这个问题的灵感来自一位同事,他确实不应该被允许靠近数据库(现在不允许)

【问题讨论】:

    标签: postgresql conditional boundary


    【解决方案1】:

    当您提取一系列数据时,实际发生的情况是 PostgreSQL 正在针对条目的该字段检查布尔表达式值。如果它满足被视为有效的所有条件,它将被拉取。

    PostgreSQL 中的示例

    SELECT
        fields
    FROM
        table
    WHERE
        (fieldX BETWEEN lower_bounds1 AND upper_bounds1
    OR
        fieldX BETWEEN lower_bounds2 AND upper_bounds2)
    ;
    

    正如您所看到的,当您为要与之比较的值设置边界(语句之间)时,最终会计算为布尔值。当您想要评估多个值时,您也需要有多个布尔值进行比较。这意味着您需要决定如何他们应该比较。如果它是同一个字段,并且在不同的比较中,并且其中至少一个需要为真,那么您需要使用 OR 语句将两个布尔值连接在一起形成一个比较。

    BETWEEN 语句和范围

    Between 确实是 Less ThanGreater Than 的组合,以更方便的方式编写它,更容易看到什么值必须在范围内才能被视为有效。

    between 语句可以用以下方式重写

    SELECT
        fields
    FROM
        table
    WHERE
        fieldX >= lower_bounds
    AND
        fieldX <= upper_bounds
    ;
    

    组合示例

    SELECT *
    FROM table t
    WHERE
        t.field1 = value
    AND
        (
            (t.field2 BETWEEN lower1 AND uppper1)
        OR
            (t.field2 BETWEEN lower2 AND uppper2)
        )
    ;
    

    实际上,这与以下 IF 语句非常接近

    if(exp1 && (exp2 || exp3){
    //do things here because it's valid
    }
    

    此示例将选择所有值满足第一个条件的行和第二个条件中的任何一个。

    为什么会起作用

    这些概念之所以有效,是因为一种叫做布尔逻辑的东西。这需要解释很多,但是互联网上的很多人对此都有很好的指导。满足表达式,就可以拉取非常复杂的数据集。

    其他类型的比较

    更多信息可以在 PostgreSQL 的文档中轻松找到,但是 WHERE 子句实际上只是寻找可以评估为真值的表达式。您可以使用连词(AND)、选项(OR)、排他(XOR1)或分隔符( NAND2) 在单个查询中连接多个表达式。除了在 WHERE 子句中嵌套条件之外,您还可以创建一些非常复杂的查询来准确获取您想要的数据。


    1:XOR 实际上并不是 PostgreSQL 的一部分。要使用类似的东西,您需要将多个边界与排除项连接在一起

    SELECT
    A,
    B
    FROM
    (
    VALUES
        (false, false),
        (false, true),
        (true, false),
        (true, true)
    )
    AS data(A, B)
    WHERE
        ( A and not B) or ( not A and B)
    ;
    

    2:NAND 表示非与。这与 OR 的区别在于,它还将所有错误条件评估为 true

    SELECT
    A,
    B
    FROM
    (
    VALUES
        (false, false),
        (false, true),
        (true, false),
        (true, true)
    )
    AS data(A, B)
    WHERE
        not A or not B
    ;
    

    【讨论】:

      猜你喜欢
      • 2020-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多