【问题标题】:Postgres query to find multiple records with a particular repeat count within a tablePostgres 查询以在表中查找具有特定重复计数的多条记录
【发布时间】:2022-11-11 00:12:48
【问题描述】:

我有 2 张表客户和订单。

第一个问题:

这是客户的主表,其中包含客户编号、客户名称、活动标志等几列。表可能包含相同客户编号的 2 条或更多记录,但根据业务逻辑,理想情况下一次只有 1 条记录积极点。我需要找到只有 1 条记录并且应该处于活动状态的客户。

我写的查询:

select customer_number, count(*) 
from customers c 
where active = false 
group by customer_number 
having count(*) = 1;

这将返回有 2 条记录且只有 1 条未处于活动状态的客户。

问题2:

除了客户表,我们还有另一个表是订单表,它包含客户编号(与客户表中相同)、交货日期、订单编号、插入时间等列。 我需要找到 ACTIVE 为 false 且自 180 天以来没有下过任何订单的客户。 (插入时间::日期 - 180)。

我所尝试的并没有给我想要的输出,因为在回溯测试中我发现数据是错误的

select om.customer_number, 
       c.customer_name, 
       om.deliverydate, 
       om.insert_time  
from customers c, order_master om 
where 
om.customer_number in 
   (
     select c2.customer_number  
     from customers c2 
     where c2.active = false 
     group by c2.customer_number 
    having count(*) =1
    ) 
and c.customer_number = om.customer_number 
group by om.customer_number, c.customer_name, 
         om.deliverydate, om.insert_time 
having max(om.insert_time::date) < '2022-06-01' ;

我尝试过的查询,我已经在我的问题中提到了它们。请检查一下。

【问题讨论】:

  • where active = false 发生在 group by 之前。您需要使用子查询或with 子句。对于第二个,您需要一个子查询或with 子句。

标签: java sql postgresql


【解决方案1】:

对于第一个问题,查找只有 1 条记录并且应该处于活动状态的客户,您可以使用条件聚合或过滤计数,如下所示:

select customer_number
from Customers c 
group by customer_number 
having count(*) = 1 and count(*) filter (where active) = 1;

对于第二个问题,查找 ACTIVE 为 false 且自 180 天以来未下过任何订单的客户, 请尝试以下操作:

select cu.customer_number
from order_master om join 
  (
    select customer_number
    from Customers c 
    group by customer_number 
    having count(*) filter (where active) = 0
   ) cu
on om.customer_number = cu.customer_number
group by cu.customer_number
having max(om.insert_time) < current_date - interval '180 day'

请参阅demo

如果要获取非活动客户的所有订单详细信息,可以将上述查询与订单表连接起来,如下所示:

with inactive_cust as
(
  select cu.customer_number, cu.customer_name
  from order_master om join 
  (
    select customer_number, customer_name
    from Customers c 
    group by customer_number, customer_name
    having count(*) filter (where active) = 0
   ) cu
  on om.customer_number = cu.customer_number
  group by cu.customer_number, cu.customer_name
  having max(om.insert_time) < current_date - interval '180 day'
)

select c.customer_number, c.customer_name,
       o.order_number, o.insert_time
from inactive_cust c join order_master o
on c.customer_number = o.customer_number

请参阅demo

【讨论】:

  • 您的第一个查询运行良好。但是,我想在第二个查询中获取其他信息,
  • 嗨,艾哈迈德,我已经发布了对修改您的查询后得到的结果的评论。所以你能不能也看看它。
【解决方案2】:

@Ahmed-您的两个查询都很好。

但是在第二个查询中,我想将其他数据提取到其中,所以我所做的是-

select om.customer_number, cu.customer_name, om.order_number ,om.insert_time 
from order_master om join 
  (
    select customer_number, customer_name
    from Customers c 
    group by customer_number, customer_name 
    having count(*) filter (where active) = 0
   ) cu
on om.customer_number = cu.customer_number
group by om.customer_number , cu.customer_name, om.insert_time,om.order_number 
 having max(om.insert_time) < current_date - interval '180 day';

When I tried the query shared by you -

        select om.customer_number
        from order_master om join 
      (
        select customer_number
        from Customers c 
        group by customer_number 
        having count(*) filter (where active) = 0
       ) cu
    on om.customer_number = cu.customer_number
    group by om.customer_number
    having max(om.insert_time) < current_date - interval '180 day';

它给了我大约 4K 的结果,当我尝试修改时,在查询中添加每一列后,结果计数呈指数增长,直到 75K 甚至更多。

它还向我展示了 max(om.insert_time) 远大于 180 天的记录

【讨论】:

    猜你喜欢
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-04
    • 1970-01-01
    • 2022-12-06
    • 2017-05-26
    相关资源
    最近更新 更多