我有两张桌子。一个存储“位置”:
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测试,而不是对每个单独的位置,即测试需要应用于每个位置,并且仅返回通过测试的那些位置。
有什么建议吗?
答案 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
答案 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;