简体   繁体   中英

selecting multiple columns but group by only one in postgres

I have a simple table in postgres:

remoteaddr        count
142.4.218.156     592
158.69.26.144     613
167.114.209.28    618

Which I pulled using the following:

select remoteaddr,
count (remoteaddr)
from domain_visitors
group by remoteaddr
having count (remoteaddr) > 500

How do I select additional columns and still only group by remoteaddr ?

Option 1: You could use the array_agg() function to concatenate the additional column values into a grouped list:

SELECT 
   remoteaddr, 
   array_agg(DISTINCT username) AS unique_users, 
   array_agg(username) AS repeated_users, 
   count(remoteaddr) as remote_count
FROM domain_visitors
GROUP BY remoteaddr;

See this SQL Fiddle . This query would return something like the below:

+----------------+---------------------------------+-----------------------------------------------------------------------------------------------------+--------------+
|   remoteaddr   |          unique_users           |                                           repeated_users                                            | remote_count |
+----------------+---------------------------------+-----------------------------------------------------------------------------------------------------+--------------+
|  142.4.218.156 | anotheruser,user9688766,vistor1 | user9688766,anotheruser,vistor1,vistor1,vistor1,vistor1,vistor1,anotheruser,anotheruser,anotheruser |           10 |
|  158.69.26.144 | anotheruser,user9688766         | anotheruser,user9688766,user9688766,user9688766,user9688766                                         |            5 |
| 167.114.209.28 | vistor1                         | vistor1                                                                                             |            1 |
+----------------+---------------------------------+-----------------------------------------------------------------------------------------------------+--------------+

Option 2: You could put your first query in a common table expression (aka a "WITH" clause), and join it against the original table, like this:

WITH grouped_addr AS (
  SELECT remoteaddr, count(remoteaddr) AS remote_count
  FROM domain_visitors
  GROUP BY remoteaddr
)

SELECT ga.remoteaddr, dv.username, ga.remote_count
FROM grouped_addr ga
INNER JOIN domain_visitors dv
ON ga.remoteaddr = dv.remoteaddr
WHERE remote_count > 500;

Here is a SQL Fiddle .

Bear in mind that this will return repeated results for any additional columns (in this example, username ). This is not usually what you want. Note each of the SELECT examples in the Fiddles and see which best suits your purpose.

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