【问题标题】:SQL select value from one column based on values in another columnSQL 根据另一列中的值从一列中选择值
【发布时间】:2018-03-04 07:08:43
【问题描述】:

我有两张桌子。一店“地点”:

TABLE location (
    ID               serial             PRIMARY KEY,
    name             text               NOT NULL,
    description      text               NOT NULL
);

每个位置都有很多行“数据”:

TABLE data(
    ID               smallint           REFERENCES location(ID),
    date             date,               
    rainfall         int                
);

我想查找所有具有跨越给定时间段的“数据”的位置。我试过这个:

SELECT location.ID, location.name FROM location                    
    JOIN data ON data.id = location.id 
    WHERE (SELECT MIN(data.date) FROM data) <= '$start_date' 
           AND 
          (SELECT MAX(data.date) FROM data) >= '$end_date' 
    ORDER BY location.ID;

但它似乎将 MIN 和 MAX 测试应用于所有数据,而不是每个单独的位置,即测试需要应用于每个位置,并且只返回那些通过测试的位置。

有什么建议吗?

【问题讨论】:

    标签: sql postgresql join where


    【解决方案1】:

    只需按位置聚合,然后从 HAVING 子句断言最小值/最大值:

    SELECT
        l.ID,
        l.name
    FROM location l                 
    INNER JOIN data d
        ON d.id = l.id
    GROUP BY
        l.ID
    HAVING
        MIN(data.date) <= '$start_date' AND
        MAX(data.date) >= '$end_date' 
    ORDER BY
        l.ID;
    

    【讨论】:

      【解决方案2】:

      当您说跨越给定时间段时,为什么不使用between,如下所示

      SELECT location.ID, location.name FROM location location
      JOIN data d ON d.id = location.id WHERE d.date between '$start_date' AND '$end_date' ORDER BY location.ID;

      请注意,此处包含两个日期

      【讨论】:

        【解决方案3】:

        您可以加入这些值的查询结果并在where 条件中使用它

        SELECT location.ID, location.name FROM location                    
        JOIN data ON data.id = location.id 
        JOIN (
            SELECT MIN(date) AS _min,MAX(date) AS _max,id
            FROM data
            GROUP BY id
        ) T ON T.id = location.id
        WHERE T._min <= '$start_date' AND T._max >= '$end_date' 
        ORDER BY location.ID;
        

        澄清一下 - 我知道您想要在这些时间跨度内获得所有 locationsdata data(示例暗示这就是您想要的)

        如果您想获得在时间范围内“发生”的所有data,这不是您的解决方案,您需要@jusermar10 或@Yogs 提供的between 解决方案

        【讨论】:

        • 谢谢 - 我实际上只想要具有所需数据的位置。 @Tim Biegeleisen 的答案对我有用。
        【解决方案4】:

        您可以使用 between 子句来获得所需的结果

        SELECT l.ID, l.name FROM location l                   
            inner JOIN data d ON d.id = l.id 
            WHERE  d.date between '$start_date' and '$end_date' group by l.id
        

        【讨论】:

          【解决方案5】:

          当你说跨越给定时间段时,我想你的意思是只输出那些所有data.date 都在$start_date$end_date 之间的位置。

          在这种情况下,这个查询应该可以工作:

          SELECT location.ID, location.NAME FROM locations, data
          WHERE locations.ID=data.ID
          GROUP BY locations.ID
          HAVING min(data.date) >= '$start_date' and max(data.date) <= $end_date;
          

          【讨论】:

            猜你喜欢
            • 2012-01-30
            • 1970-01-01
            • 2022-09-29
            • 2018-01-02
            • 1970-01-01
            • 1970-01-01
            • 2021-02-22
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多