SQL选择COUNT(*)>最低人数

时间:2018-03-11 08:18:49

标签: sql postgresql select

我有两张桌子。一个商店"地点":

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),因为它在所需的时间段内没有所需数量的值。

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 byhaving执行所需操作。一种方法是:

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;