Concatenate multiple rows and fields in a table - mysql

I want to concatenate fields intersected part of the same table
id user_id user_ip
4 971 108.54.218.114
5 972 108.54.218.114
6 973 108.54.218.114
7 974 108.54.218.114
8 975 107.222.159.246
9 975 98.54.818.133
In the example above, we can see that the user with the IP address (108.54.218.114) address to create multiple accounts with the following account IDs (971, 972, 973, 974), but also that the user with the account ID (975) is connect from the following IP addresses (107.222.159.246, 98.54.818.133)
I want to format the results like this
user_id user_ip
971,972,973,974 108.54.218.114
975 107.222.159.246, 98.54.818.133
MySQL
SELECT
GROUP_CONCAT(DISTINCT users_log.user_id) AS ID_LOG,
GROUP_CONCAT(DISTINCT users_log.user_ip) AS IP_LOG
FROM users_log
GROUP BY users_log.user_id
ORDER BY users_log.user_id DESC
If anyone can help me?
Thank you in advance for your help

There is another recent question (which I can't find) on SO very close to this. I asked about the intersecting row because of the (for lack of better term) recursiveness of this type of solution.
Here is SQL to give you your exact answer for that exact sample set.
SELECT user_id, GROUP_CONCAT(DISTINCT user_ip) AS user_ip
FROM users_log
GROUP BY user_id
HAVING COUNT(*) >1
UNION
SELECT GROUP_CONCAT(DISTINCT user_id) AS user_id, user_ip
FROM users_log
GROUP BY user_ip
HAVING COUNT(*) >1;

Related

Calculate Average of Text Value Mysql [duplicate]

Using PHP and MySQL, I want to query a table of postings my users have made to find the person who has posted the most entries.
What would be the correct query for this?
Sample table structure:
[id] [UserID]
1 johnnietheblack
2 johnnietheblack
3 dannyrottenegg
4 marywhite
5 marywhite
6 johnnietheblack
I would like to see that "johnnietheblack" is the top poster, "marywhite" is second to best, and "dannyrottenegg" has the least
Something like:
SELECT COUNT(*) AS `Rows`, UserID
FROM `postings`
GROUP BY UserID
ORDER BY `Rows` DESC
LIMIT 1
This gets the number of rows posted by a particular ID, then sorts though the count to find the highest value, outputting it, and the ID of the person. You'll need to replace the 'UserID' and 'postings' with the appropriate column and field though.
I believe this should work...
SELECT user_id, COUNT(*) FROM postings ORDER BY COUNT(*) GROUP BY user_id LIMIT 1
Assuming posting is a tuple (user_id, recipient_user_id), where each row represents one posting, from user_id to recipient_user_id:
select user_id, count(*) as posts
from postings
group by user_id
having count(*) = max(count(*)) ;

How to Count Distinct with Group By and the entire Column

I'm having a hard time wording what I need/wording the search result, so apologies if this is a stupid question/has been answered before. I'm trying to write a query in SQL for a table such as below:
Country Unique_ID
US 123
US 124
UK 125
Australia 126
That will output the follow table:
Country Count_Distinct
US 2
UK 1
Australia 1
All 4
I know I can select the countryid and count distinct the country codes, and I know I can just count distinct the countryid codes to get the "All" number. I can't figure out how to write a query to get the follow output that's not two separate queries.
If you need information or clarification please let me know. Thanks!
Use WITH ROLLUP:
select Country, count(distinct Unique_ID) Count_Distinct
from mytable
group by Country
with rollup
If you want the text "All" (you get a null for the country by default), wrap it in another query to change the null to "All":
select coalesce(Country, "All") Country, Count_Distinct
from (
select Country, count(distinct Unique_ID) Count_Distinct
from mytable
group by Country
with rollup
) x
Can you please try this :
select country,count(distinct unique_id) as count distinct
from table
group by rollup(country)

SELECT DUPLICATE MAX(ID)

I have data similar to the following in my table:
id territory_id platform_id title_id other columns
1 US ITUNES 155 10 others columns...
100 US ITUNES 155 10 others columns...
101 FR ITUNES 155 10 others columns...
I need to SELECT MAX(ID) on all duplicate rows, based on (territory_id, platform_id, title_id).
The query on the above data set should return the id 100, since the only duplicate above based on (territory_id, platform_id, title_id) is ('US', 'ITUNES', 155) and the MAX(ID) of that duplicate entry is 100 (not 1).
How would I build this query? So far I have:
SELECT id FROM table GROUP BY territory_id, platform_id, title_id
You can GROUP BY the 3 fields, then using HAVING clause you can identify duplicates. Using MAX you can get the max ID for each of those groups having duplicates:
SELECT MAX(ID), territory_id, platform_id, title_id
FROM MyTable
GROUP BY territory_id, platform_id, title_id
HAVING COUNT(*) > 1
SQL Fiddle Demo
I think you are looking for something like this
select DISTINCT territory_id, max(ID)
,platform_id,title_id
from test t
GROUP BY territory_id,platform_id,title_id
HAVING COUNT(*)>1
Here are the results from the replicated table
territory_id id platform_id title_id
US 100 ITUNES 155
If you needed to you could go one step further and declare a variable if this will make its way to a report.

Counts which string appears the most

I have a table for example:
Names Details
--------------
wilson admin
david member
wilson admin
wilson admin
sam member
david member
Now what i want to achieve is show a table like this
Names Details count
--------------------
wilson admin 3
david member 2
sam member 1
I want to show the names according to how many times they appear
SELECT Name, Detail, COUNT(*) as Count
FROM MyTable
GROUP BY Name, Detail
ORDER BY Count DESC;
Since you have more than one column in your output table SELECT, you should group by both columns.
I found the answer already
SELECT names, COUNT(names) AS count
FROM my_table
GROUP BY names ORDER BY count DESC
Try this, use the GROUP BY and COUNT
SELECT Names, Details, COUNT(NAMES) as `count` FROM `table` GROUP BY `Names`

Select distinct column along with some other columns in MySQL

I can't seem to find a suitable solution for the following (probably an age old) problem so hoping someone can shed some light. I need to return 1 distinct column along with other non distinct columns in mySQL.
I have the following table in mySQL:
id name destination rating country
----------------------------------------------------
1 James Barbados 5 WI
2 Andrew Antigua 6 WI
3 James Barbados 3 WI
4 Declan Trinidad 2 WI
5 Steve Barbados 4 WI
6 Declan Trinidad 3 WI
I would like SQL statement to return the DISTINCT name along with the destination, rating based on country.
id name destination rating country
----------------------------------------------------
1 James Barbados 5 WI
2 Andrew Antigua 6 WI
4 Declan Trinidad 2 WI
5 Steve Barbados 4 WI
As you can see, James and Declan have different ratings, but the same name, so they are returned only once.
The following query returns all rows because the ratings are different. Is there anyway I can return the above result set?
SELECT (distinct name), destination, rating
FROM table
WHERE country = 'WI'
ORDER BY id
Using a subquery, you can get the highest id for each name, then select the rest of the rows based on that:
SELECT * FROM table
WHERE id IN (
SELECT MAX(id) FROM table GROUP BY name
)
If you'd prefer, use MIN(id) to get the first record for each name instead of the last.
It can also be done with an INNER JOIN against the subquery. For this purpose the performance should be similar, and sometimes you need to join on two columns from the subquery.
SELECT
table.*
FROM
table
INNER JOIN (
SELECT MAX(id) AS id FROM table GROUP BY name
) maxid ON table.id = maxid.id
The problem is that distinct works across the entire return set and not just the first field. Otherwise MySQL wouldn't know what record to return. So, you want to have some sort of group function on rating, whether MAX, MIN, GROUP_CONCAT, AVG, or several other functions.
Michael has already posted a good answer, so I'm not going to re-write the query.
I agree with #rcdmk . Using a DEPENDENT subquery can kill performance, GROUP BY seems more suitable provided that you have already INDEXed the country field and only a few rows will reach the server. Rewriting the query giben by #rcdmk , I added the ORDER BY NULL clause to suppress the implicit ordering by GROUP BY, to make it a little faster:
SELECT MIN(id) as id, name, destination as rating, country
FROM table WHERE country = 'WI'
GROUP BY name, destination ORDER BY NULL
You can do a GROUP BY clause:
SELECT MIN(id) AS id, name, destination, AVG(rating) AS rating, country
FROM TABLE_NAME
GROUP BY name, destination, country
This query would perform better in large datasets than the subquery alternatives and it can be easier to read as well.