简体   繁体   中英

GROUP BY column HAVING COUNT(*) > 1, and still show all the rows?

I'm only trying to display rows that have the same GROUP_CONCAT() column value. When using GROUP BY at the end, it just showing the last full name in the table because of the GROUP BY country. Is it still possible to show all rows when I group by country? This is my sql:

SELECT firstname, lastname, country, COUNT(*) c
FROM (
   SELECT firstname, lastname, 
   GROUP_CONCAT(
      DISTINCT f.countryname
      ORDER BY f.countryname ASC
      SEPARATOR ','
   ) AS country
   FROM person p 
   INNER JOIN favoritecountry f 
   ON p.id = f.id 
   GROUP BY firstname, lastname 
) t 
GROUP BY country 
HAVING c > 1
ORDER BY c DESC;

My result is:

+-----------+----------+--------------+---+
| firstname | lastname |   country    | c |
+-----------+----------+--------------+---+
| bill      | smith    | Poland,Spain | 2 |
+-----------+----------+--------------+---+

Instead, I want something like this:

+-----------+----------+--------------+---+
| firstname | lastname |   country    | c |
+-----------+----------+--------------+---+
| bill      | smith    | Poland,Spain | 2 |
| phil      | cooper   | Poland,Spain | 2 |
+-----------+----------+--------------+---+

New to SQL, so need some help

Based on you expected result you should cross join the count for group_concat country with the name for country

    select  t2.firstname, t2.lastname, t2.country
    from   (
        SELECT firstname, lastname, 
        GROUP_CONCAT(
          DISTINCT f.countryname
          ORDER BY f.countryname ASC
          SEPARATOR ','
       ) AS country
       FROM person p 
       INNER JOIN favoritecountry f 
       ON p.id = f.id 
       GROUP BY firstname, lastname 
    ) t2
    cross join  (
        select t1.country, count(*) my_count
        from (
            SELECT firstname
             , lastname, 
            GROUP_CONCAT( DISTINCT f.countryname
                ORDER BY f.countryname ASC
                SEPARATOR ','
                ) AS country
            FROM person p 
            INNER JOIN favoritecountry f ON p.id = f.id 
            GROUP BY firstname, lastname 
        )   t 

    ) t1 on t1.country = t2.country

As of MySQL 8 you can use window functions (eg COUNT OVER ) for such tasks:

SELECT firstname, lastname, countries, cnt
FROM
(
  SELECT firstname, lastname, countries, COUNT(*) over (PARTITION BY countries) AS cnt
  FROM
  (
     SELECT
       p.firstname, p.lastname, 
       GROUP_CONCAT(DISTINCT f.countryname
                    ORDER BY f.countryname ASC
                    SEPARATOR ',') AS countries
     FROM person p 
     INNER JOIN favoritecountry f ON p.id = f.id 
     GROUP BY p.firstname, p.lastname 
  ) grouped
) counted
WHERE cnt > 1
ORDER BY cnt DESC, countries;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM