Oracle SQL - 将行保留在特定列类别中列值较多的组中

Oracle SQL - Keep rows within group where there are larger number of values for column, in a specific column category

我需要弄清楚如何从下面的 table 中获取结果,并且只显示图像中绿色突出显示的行。在每个 account_id/site_id 组合中(示例中显示了两个 - 123/usa 和 456/can),我只需要保留 group_ids,其中 Y(标志)的数量更多品牌(如 side_id“罐头”所示 - group_id 1 中该品牌的 Y 多于 group_id 2 中的 Y。在 account_id/site 组合中,如果有两个 group_ids 具有超过两个 Y 的品牌,则将它们都保留(如 site_id “美国”中所示)。

group_id account_id site_id brand flag
1 123 usa toyota N
1 123 usa toyota N
1 123 usa tesla Y
1 123 usa tesla Y
2 123 usa toyota Y
2 123 usa toyota N
2 123 usa tesla Y
2 123 usa tesla N
3 123 usa toyota Y
3 123 usa toyota N
3 123 usa tesla Y
3 123 usa tesla N
4 123 usa toyota Y
4 123 usa toyota Y
4 123 usa tesla N
4 123 usa tesla N
1 456 can honda Y
1 456 can honda Y
1 456 can honda Y
2 456 can honda Y
2 456 can honda N
2 456 can honda Y

通过组合使用window个函数,可以统计每个group/account/site/brand的Y flags个数,然后求出用另一个解析函数划分的最大Y flags个数,然后只有 return 这两个值匹配的行。

查询

WITH
    grps (GROUP_ID,
          account_id,
          site_id,
          brand,
          flag)
    AS
        (SELECT 1, 123, 'usa', 'toyota', 'N' FROM DUAL
         UNION ALL
         SELECT 1, 123, 'usa', 'toyota', 'N' FROM DUAL
         UNION ALL
         SELECT 1, 123, 'usa', 'tesla', 'Y' FROM DUAL
         UNION ALL
         SELECT 1, 123, 'usa', 'tesla', 'Y' FROM DUAL
         UNION ALL
         SELECT 2, 123, 'usa', 'toyota', 'Y' FROM DUAL
         UNION ALL
         SELECT 2, 123, 'usa', 'toyota', 'N' FROM DUAL
         UNION ALL
         SELECT 2, 123, 'usa', 'tesla', 'Y' FROM DUAL
         UNION ALL
         SELECT 2, 123, 'usa', 'tesla', 'N' FROM DUAL
         UNION ALL
         SELECT 3, 123, 'usa', 'toyota', 'Y' FROM DUAL
         UNION ALL
         SELECT 3, 123, 'usa', 'toyota', 'N' FROM DUAL
         UNION ALL
         SELECT 3, 123, 'usa', 'tesla', 'Y' FROM DUAL
         UNION ALL
         SELECT 3, 123, 'usa', 'tesla', 'N' FROM DUAL
         UNION ALL
         SELECT 4, 123, 'usa', 'toyota', 'Y' FROM DUAL
         UNION ALL
         SELECT 4, 123, 'usa', 'toyota', 'Y' FROM DUAL
         UNION ALL
         SELECT 4, 123, 'usa', 'tesla', 'N' FROM DUAL
         UNION ALL
         SELECT 4, 123, 'usa', 'tesla', 'N' FROM DUAL
         UNION ALL
         SELECT 1, 456, 'can', 'honda', 'Y' FROM DUAL
         UNION ALL
         SELECT 1, 456, 'can', 'honda', 'Y' FROM DUAL
         UNION ALL
         SELECT 1, 456, 'can', 'honda', 'Y' FROM DUAL
         UNION ALL
         SELECT 2, 456, 'can', 'honda', 'Y' FROM DUAL
         UNION ALL
         SELECT 2, 456, 'can', 'honda', 'N' FROM DUAL
         UNION ALL
         SELECT 2, 456, 'can', 'honda', 'Y' FROM DUAL)
  SELECT g3.GROUP_ID,
         g3.account_id,
         g3.site_id,
         g3.brand,
         g3.flag
    FROM (SELECT g2.*, MAX (g2.y_flag_cnt) OVER (PARTITION BY account_id) AS max_y_flag_cnt
            FROM (SELECT g.*,
                         SUM (CASE WHEN flag = 'Y' THEN 1 ELSE 0 END)
                             OVER (PARTITION BY GROUP_ID,
                                                account_id,
                                                site_id,
                                                brand)    AS y_flag_cnt
                    FROM grps g) g2) g3
   WHERE flag = 'Y' AND y_flag_cnt = max_y_flag_cnt
ORDER BY account_id, GROUP_ID;

输出

   GROUP_ID    ACCOUNT_ID    SITE_ID     BRAND    FLAG
___________ _____________ __________ _________ _______
          1           123 usa        tesla     Y
          1           123 usa        tesla     Y
          4           123 usa        toyota    Y
          4           123 usa        toyota    Y
          1           456 can        honda     Y
          1           456 can        honda     Y
          1           456 can        honda     Y