Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql GROUP BY未按预期工作_Sql_Postgresql_Aggregate - Fatal编程技术网

Sql GROUP BY未按预期工作

Sql GROUP BY未按预期工作,sql,postgresql,aggregate,Sql,Postgresql,Aggregate,这是我的样本表,只有一点信息 select * from juniper_fpc'; id | router | part_name -----------+-----------+-------------------- 722830939 | BBBB-ZZZ1 | MPC-3D-16XGE-SFPP 722830940 | BBBB-ZZZ1 | MPC-3D-16XGE-SFPP 723103163 | AAAA-ZZZ1

这是我的样本表,只有一点信息

select * from juniper_fpc';       
    id     |  router   |     part_name      
-----------+-----------+--------------------
 722830939 | BBBB-ZZZ1 | MPC-3D-16XGE-SFPP 
 722830940 | BBBB-ZZZ1 | MPC-3D-16XGE-SFPP 
 723103163 | AAAA-ZZZ1 | DPCE-R-40GE-SFP   
 723103164 | AAAA-ZZZ1 | MPC-3D-16XGE-SFPP 
 723103172 | AAAA-ZZZ1 | DPCE-R-40GE-SFP   
 722830941 | BBBB-ZZZ1 | MPC-3D-16XGE-SFPP
我要做的是从router列中识别只有part_名称条目以MPC开头的元素。我想到的是这个,但它是错误的,因为它列出了上述两个元素

SELECT   router
FROM     juniper_fpc
WHERE    part_name LIKE 'MPC%'
GROUP BY router
ORDER BY router;
  router   
-----------
 AAAA-ZZZ1
 BBBB-ZZZ1

如果您的意思是只选择那些路由器,它们的所有部件名称都以MPC开头,那么您的查询应该是:

SELECT   s.router
FROM     juniper_fpc s
WHERE    NOT EXISTS(select distinct id from juniper_fpc t
                    where t.id = s.id part_name NOT LIKE 'MPC%')
GROUP BY s.router
ORDER BY s.router;

如果您的意思是只选择那些路由器,它们的所有部件名称都以MPC开头,那么您的查询应该是:

SELECT   s.router
FROM     juniper_fpc s
WHERE    NOT EXISTS(select distinct id from juniper_fpc t
                    where t.id = s.id part_name NOT LIKE 'MPC%')
GROUP BY s.router
ORDER BY s.router;

假设您想要的路由器只有部分名称,如“MPC%”,则可以使用条件计数:

select * from (
  select router, 
    count(case when part_name like 'MPC%' then 1 else null end) as cnt_mpc,
    count(*) as cnt_overall
  from juniper_fpc  
  group by router) v_inner
where cnt_mpc = cnt_overall
这可以写得更紧凑,尽管可读性稍差

  select router
  from juniper_fpc  
  group by router
  having count(case when part_name like 'MPC%' then 1 else null end)  = count(*) 

假设您想要的路由器只有部分名称,如“MPC%”,则可以使用条件计数:

select * from (
  select router, 
    count(case when part_name like 'MPC%' then 1 else null end) as cnt_mpc,
    count(*) as cnt_overall
  from juniper_fpc  
  group by router) v_inner
where cnt_mpc = cnt_overall
这可以写得更紧凑,尽管可读性稍差

  select router
  from juniper_fpc  
  group by router
  having count(case when part_name like 'MPC%' then 1 else null end)  = count(*) 

这应该表现良好:

SELECT j1.router
FROM  (
   SELECT   router
   FROM     juniper_fpc
   WHERE    part_name LIKE 'MPC%'
   GROUP    BY router
   ) j1
LEFT   JOIN juniper_fpc j2 ON j2.router = j1.router
                          AND j2.part_name NOT LIKE 'MPC%'
WHERE  j2.router IS NULL
ORDER  BY j1.router;
如果你做得对的话,也不存在可以工作的人:

SELECT router
FROM   juniper_fpc j
WHERE  NOT EXISTS (
   SELECT 1
   FROM   juniper_fpc
   WHERE  router = j.router
   AND    part_name NOT LIKE 'MPC%'
   )
GROUP  BY router
ORDER  BY router; 
详情:

或者,使用Postgres 9.4或更高版本的语法:

SELECT router
FROM   juniper_fpc
GROUP  BY router
HAVING count(*) = count(*) FILTER (WHERE part_name LIKE 'MPC%')
ORDER  BY router;

最好使用路由器上的索引,每个路由器的部件名。

这应该可以很好地执行:

SELECT j1.router
FROM  (
   SELECT   router
   FROM     juniper_fpc
   WHERE    part_name LIKE 'MPC%'
   GROUP    BY router
   ) j1
LEFT   JOIN juniper_fpc j2 ON j2.router = j1.router
                          AND j2.part_name NOT LIKE 'MPC%'
WHERE  j2.router IS NULL
ORDER  BY j1.router;
如果你做得对的话,也不存在可以工作的人:

SELECT router
FROM   juniper_fpc j
WHERE  NOT EXISTS (
   SELECT 1
   FROM   juniper_fpc
   WHERE  router = j.router
   AND    part_name NOT LIKE 'MPC%'
   )
GROUP  BY router
ORDER  BY router; 
详情:

或者,使用Postgres 9.4或更高版本的语法:

SELECT router
FROM   juniper_fpc
GROUP  BY router
HAVING count(*) = count(*) FILTER (WHERE part_name LIKE 'MPC%')
ORDER  BY router;

最好使用路由器上的索引,每个路由器的部件名。

您也可以在此处打开函数:

SELECT
    *
FROM
    (
        SELECT 
            router,
            part_name,
            COUNT(distinct part_name) OVER (PARTITION BY router) as count_of_distinct_parts
        FROM juniper_fpc
    )subqry
WHERE part_name like 'MPC%' AND count_of_distinct_parts = 1

如果此查询范围扩大,这将为更复杂的情况打开大门。

您也可以在此处选择窗口功能:

SELECT
    *
FROM
    (
        SELECT 
            router,
            part_name,
            COUNT(distinct part_name) OVER (PARTITION BY router) as count_of_distinct_parts
        FROM juniper_fpc
    )subqry
WHERE part_name like 'MPC%' AND count_of_distinct_parts = 1

如果此查询范围扩大,这将为更复杂的情况打开大门。

我看不出您的代码或输出有任何错误,根据u,这两个都应该返回!您的输入数据包含| AAAA-ZZZ1 | MPC-3D-16XGE-SFPP |和| BBBB-ZZZ1 | MPC-3D-16XGE-SFPP |,因此PostgreSQL返回正确的结果。您是否需要只包含部分名称(如“MPC”)而不包含其他名称的记录?也许您希望看到MPC-3D-16XGE-SFPP没有路由器名称“bbbbb-ZZZ1”?在这种情况下,您应该分组并按部件名称排序。我看不出您的代码或输出有任何错误,根据u,这两个都应该返回!您的输入数据包含| AAAA-ZZZ1 | MPC-3D-16XGE-SFPP |和| BBBB-ZZZ1 | MPC-3D-16XGE-SFPP |,因此PostgreSQL返回正确的结果。您是否需要只包含部分名称(如“MPC”)而不包含其他名称的记录?也许您希望看到MPC-3D-16XGE-SFPP没有路由器名称“bbbbb-ZZZ1”?在这种情况下,您应该按部件名称分组和排序。问题:您不能在子查询中引用未聚合的s.id;区别是没有用的;缺少和.问题:无法在子查询中引用未聚合的s.id;区别是没有用的;失踪和失踪。