簡體   English   中英

GROUP BY無法正常工作

[英]GROUP BY isn't working as expected

這是我的示例表,僅包含一些信息。

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

我想做的是從路由器列中標識僅以MPC開頭的part_name條目的元素。 我想出的是這個,但這是錯誤的,因為它列出了以上兩個元素。

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

假設您只需要part_name之類的路由器,例如“ 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(*) 

SQL小提琴

這應該表現良好:

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;

如果沒有問題,@ sagi的想法 NOT EXISTS存在的人也可以使用:

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; 

細節:

SQL提琴。

或者, @ Frank的想法帶有Postgres 9.4或更高版本的語法:

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

最好為每個(router, partname)上的(router, partname)建立索引。

如果您的意思是僅選擇那些路由器,它們的所有部件名稱都以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;

您也可以在這里使用窗口函數:

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

如果此查詢范圍擴展,則將為更復雜的條件敞開大門。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM