我有两张桌子。一个商店"地点":
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
);
我想找到所有包含"数据"跨越一定时期,至少有#34; min"该期间内的值数量。我试过这个:
SELECT location.ID, location.name
FROM location
JOIN data
ON data.id = location.id
GROUP BY location.id
HAVING MIN(data.date) <= '$start_date'
AND
MAX(data.date) >= '$end_date'
AND
(SELECT COUNT(*) FROM data WHERE data.date >= '$start_date' AND data.date <= '$end_date') >= '$min'
ORDER BY location.ID
如果我取出第二个最后一行(SELECT COUNT行),它会正确返回数据跨越所需期间的位置(但不具有所需期间内的值数量大于约束的约束)或等于&#34; min&#34;)。
谁能告诉我如何施加约束?即。我的&#34; SELECT COUNT行&#34;。
出了什么问题以下示例数据可能有助于澄清我的问题:
示例数据:
location:
ID = 1, name = "London", description = "test location 1"
ID = 2, name = "New York", description = "test location 2"
数据:
ID = 1, date = 2001-01-01, rainfall = 0.0
ID = 1, date = 2001-01-02, rainfall = 0.0
ID = 1, date = 2001-01-03, rainfall = 0.0
ID = 1, date = 2001-01-04, rainfall = 0.0
ID = 1, date = 2001-01-05, rainfall = 0.0
ID = 1, date = 2001-01-06, rainfall = 0.0
ID = 1, date = 2001-01-07, rainfall = 0.0
ID = 2, date = 2001-01-01, rainfall = 0.0
ID = 2, date = 2001-01-04, rainfall = 0.0
ID = 2, date = 2001-01-05, rainfall = 0.0
ID = 2, date = 2017-01-01, rainfall = 0.0 # Not within the desired period, so is excluded
ID = 2, date = 2017-01-02, rainfall = 0.0 # Not within the desired period, so is excluded
ID = 2, date = 2017-01-03, rainfall = 0.0 # Not within the desired period, so is excluded
ID = 2, date = 2017-01-04, rainfall = 0.0 # Not within the desired period, so is excluded
如果我搜索2001-01-01和2001-01-07之间数据且所有数据值至少为6的所有位置,则只返回位置1(ID = 1)。不应返回第二个位置(ID = 2),因为它在所需的时间段内没有所需数量的值。
答案 0 :(得分:2)
这是我的答案的新版本,因为我误解了“跨越&#39;”。我对这个问题的解释仍然是,在计算数值时,我们应该只在给定的时间内完成它
SELECT l.id, l.name
FROM location l
JOIN location_data d
ON l.id = d.id
GROUP BY l.id, l.name
HAVING MIN(d.date) <= '2017-01-01'
AND MAX(d.date) >= '2017-12-31'
AND (SELECT COUNT(b.id)
FROM location_data b
WHERE b.date BETWEEN '2017-01-01' AND '2017-12-31'
AND b.id = l.id) >= 2
我将表数据重命名为test db中的location_data,但这可能很明显:)
答案 1 :(得分:1)
首先,您应该将日期等值传递给参数,而不是字符串。其次,COUNT()
返回一个数字,因此比较应该是数字,而不是字符串。
您应该可以使用group by
和having
执行所需操作。一种方法是:
SELECT l.ID, l.name
FROM location l JOIN
data d
ON d.id = l.id
GROUP BY l.id, l.name
HAVING MIN(d.date) <= '$start_date' AND
MAX(d.date) >= '$end_date' AND
COUNT(*) >= $min
ORDER BY l.ID;