SQL根据另一列中的值从一列中选择值

时间:2018-03-04 07:08:43

标签: sql postgresql join where

我有两张桌子。一个存储“位置”:

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测试,而不是对每个单独的位置,即测试需要应用于每个位置,并且仅返回通过测试的那些位置。

有什么建议吗?

5 个答案:

答案 0 :(得分:3)

只按位置聚合,然后根据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;

答案 1 :(得分:1)

当您说跨越给定时间段时,为什么不使用下面的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;

请注意,这两个日期都包含在内

答案 2 :(得分:0)

您可以加入这些值的查询结果,并在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;

只是为了澄清一下 - 我知道你希望得到data locations在这些时间范围内data的所有data(示例暗示这是你想要的)

如果您希望获得时间范围内“发生”的所有between,这不是您的解决方案,您需要@ jusermar10或@Yogs from pynput import keyboard import time def keydet(key): return False def keypress(): def callb(key): # what to do on key-release ti1 = time.time() - t ti2 = str(ti1) # converting float value to string ti3 = ti2[0:5] # cutting the seconds ( time ) , without it , it will print like 0.233446546 print("The key", key, "Pressed For", ti3) kp = key print(kp) a = time.sleep(0.0001) return key # stop detecting more key-releases def callb1(key): # what to do on key-press return False # stop detecting more key-presses with keyboard.Listener(on_press=callb1) as listener1: # setting code for listening key-press listener1.join() t = 0 t = time.time() with keyboard.Listener(on_release=callb) as listener: # setting code for listening key-release listener.join() #Keypress Detector with keyboard.Listener(on_press=keydet) as listener: keypress() 解决方案>

答案 3 :(得分:0)

您可以使用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

答案 4 :(得分:0)

当您说跨越给定时间段时,我认为您的意思是仅输出那些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;