Postgresql 从出现次数超过n的联接表中选择行

Postgresql 从出现次数超过n的联接表中选择行,postgresql,join,group-by,count,Postgresql,Join,Group By,Count,我的问题与类似,但我使用的是PostgreSQL。我有一个类似这样的问题: select d.user_id, d.recorded_at, d.glucose_value, d.unit from diary as d join ( select u.id from health_user as u join ( select distinct user_id from care_connect where clinic_

我的问题与类似,但我使用的是PostgreSQL。我有一个类似这样的问题:

select d.user_id, d.recorded_at, d.glucose_value, d.unit
from diary as d
join (
    select u.id
    from health_user as u
    join (
        select distinct user_id
        from care_connect
        where clinic_id = 217
            and role = 'user'
            and status = 'active'
    ) as c
    on u.id = c.user_id
    where u.is_tester is false
) as cu
on d.user_id = cu.id
where d.created_at >= d.recorded_at
    and d.recorded_at < current_date and d.recorded_at >= current_date - interval '30 days'
    and d.glucose_value > 0
    and (d.state = 'wakeup' or (d.state = 'before_meal' and d.meal_type = 'breakfast'))
正如您所看到的,这已经是一个包含许多条件的长查询。现在,我只想获取来自结果中不少于四行记录的用户的记录,因此我尝试:

select d.user_id, d.recorded_at, d.glucose_value, d.unit, count(d.*)
from diary as d
join (
    select u.id
    from health_user as u
    join (
        select distinct user_id
        from care_connect
        where clinic_id = 217
            and role = 'user'
            and status = 'active'
    ) as c
    on u.id = c.user_id
    where u.is_tester is false
) as cu
on d.user_id = cu.id
where d.created_at >= d.recorded_at
    and d.recorded_at < current_date and d.recorded_at >= current_date - interval '30 days'
    and d.glucose_value > 0
    and (d.state = 'wakeup' or (d.state = 'before_meal' and d.meal_type = 'breakfast'))
group by d.user_id
having count(d.*) >= 4
然而,它抛出了一个错误,说d.recorded_at也应该添加到groupby中,但这不是我想要的。此外,对原始时间戳进行分组没有意义

我知道我可能可以加入另一个表,它们是由同一个查询生成的,但在第一行只选择d.user\u id,countd.*,但整个查询看起来很疯狂

有人能帮助我如何更好地实现这一点吗?对不起,我没有在这里放置表结构,但如果需要,我可以编辑和澄清内容。

试试这个

Select user_id, recorded_at, glucose_value, unit
From (
select d.user_id, d.recorded_at, d.glucose_value, d.unit, count(1) over (partition by d.user_id) rcnt
from diary as d
join (
    select u.id
    from health_user as u
    join (
        select distinct user_id
        from care_connect
        where clinic_id = 217
            and role = 'user'
            and status = 'active'
    ) as c
    on u.id = c.user_id
    where u.is_tester is false
) as cu
on d.user_id = cu.id
where d.created_at >= d.recorded_at
    and d.recorded_at < current_date and d.recorded_at >= current_date - interval '30 days'
    and d.glucose_value > 0
    and (d.state = 'wakeup' or (d.state = 'before_meal' and d.meal_type = 'breakfast'))
) x 
Where rcnt >= 4
试试这个:

将_查询替换为实际查询

使用with子句和exists子句


请添加第一个查询的实际输出和预期输出。@FahadAnjum已相应地编辑了我的问题。count1是什么意思?d.user\u id的分区是什么?请你在回答中多加解释好吗?以上是分析功能。当我们需要具有聚合值的详细报告时,我们可以使用它。我需要员工的工资,但我想知道支付给该员工部门的总工资。在这种情况下,我们可以使用解析函数。Count将使用GROUPBY子句。所以我们无法得到详细的结果。在您的情况下,您需要详细信息,但同时要计算记录的数量。在这种情况下,仅分析函数对您有用。否则,您必须使用子查询,它将非常复杂,并将提高性能。那么count1中的1是什么呢?没什么,它只是常数。如果我们使用特定的列,如果该列为空,那么计数不会考虑。如果使用count*,则检查所有列可能需要时间。所以为了避免这些,我们可以使用count1
+---------+---------------------+---------------+--------+
| user_id |     recorded_at     | glucose_value |  unit  |
+---------+---------------------+---------------+--------+
|   12214 | 2018-06-25 12:40:13 |            10 | mmol/L |
|   12214 | 2018-06-26 12:41:13 |            12 | mmol/L |
|   12214 | 2018-06-29 00:21:14 |            11 | mmol/L |
|   12214 | 2018-06-29 12:59:32 |            10 | mmol/L |
+---------+---------------------+---------------+--------+
Select user_id, recorded_at, glucose_value, unit
From (
select d.user_id, d.recorded_at, d.glucose_value, d.unit, count(1) over (partition by d.user_id) rcnt
from diary as d
join (
    select u.id
    from health_user as u
    join (
        select distinct user_id
        from care_connect
        where clinic_id = 217
            and role = 'user'
            and status = 'active'
    ) as c
    on u.id = c.user_id
    where u.is_tester is false
) as cu
on d.user_id = cu.id
where d.created_at >= d.recorded_at
    and d.recorded_at < current_date and d.recorded_at >= current_date - interval '30 days'
    and d.glucose_value > 0
    and (d.state = 'wakeup' or (d.state = 'before_meal' and d.meal_type = 'breakfast'))
) x 
Where rcnt >= 4
with original_query as ( your_query )
select * from original_query q1
where 
exists( select q2.user_id from original_query q2 where q1.user_id = q2.user_id
group by q2.user_id 
having count(q2.user_id) >= 4 )