MySQL find duplicates based on another column value - mysql

I have the following table
+----+------+-------+
| id | user | value |
+----+------+-------+
| 1 | 10 | A |
| 2 | 12 | B |
| 3 | 24 | A |
| 4 | 33 | C |
+----+------+-------+
I want to retreive all the duplicates users that have the same key
+----+------+-------+
| id | user | value |
+----+------+-------+
| 1 | 10 | A |
| 3 | 24 | A |
+----+------+-------+
I've tried that with no luck
SELECT DISTINCT A.user, A.value
FROM table as A
INNER JOIN ( SELECT value FROM table GROUP BY value HAVING COUNT(value) > 1 ) AS B
ON A.value = B.value

You may try below query -
SELECT id, user, value
FROM YUOR_TABLE T1
WHERE EXISTS (SELECT 1
FROM YOUR_TABLE T2
WHERE T1.value = T2.value
AND T1.user <> T2.user)

Related

Combining multiple JOINS(inner and Left)into one Select

My problem is that i have 4 tables, that i want to combine. Table1 has Tickets, Table2 with users, Table 3 with admins and Table4 with files. My Select was woring great when i had only 3 tables, without files, my select back then was something like this
SELECT
Table1.TicketNumber,
Count(Table1.TicketNumber) as "number of tickets",
Table2.UserName,
Table3.AdminName
FROM Table1
inner join
table2 on table1.ID_U=table2.ID
inner join
table3 on table1.ID_A=table3.ID
GROUP BY Table1.TicketNumber
Then i decided to add to my select another table(Table4), from which i would sum number of files for corresponding Ticket, and my Select is something like this:
SELECT
Table1.TicketNumber ,
Table1.count,
Table4.count
FROM
( SELECT TicketNumber,
count(*) AS count
FROM Table1
GROUP BY TicketNumber
)Table1
LEFT JOIN
( SELECT TickerNumber,
count(*) as count
FROM Table2
GROUP BY TicketNumber
) Table2 ON Table1.Name=Table2.Name
My problem is when i try to in somehow merge these two selects to get all that i want, i get syntax error in my INNER JOIN that Table1.ID_U doesnt exist.
Here is simplified struct of my Tables
Table1 Table 2/3
+----+--------------+------+------+----------+ +----+----------------+
| ID | TicketNumber | ID_U | ID_A | SomeData | | ID | User/Admin Name|
+----+--------------+------+------+----------+ +----+----------------+
| 0 | T001 | 1 | 1 | blah | | 0 | Name |
| 1 | T002 | 2 | 3 | blah | | 1 | Name |
| 2 | T002 | 2 | 3 | blah | | 2 | Name |
| 3 | T003 | 2 | 2 | blah | | 3 | Name |
| 4 | T004 | 3 | 1 | blah | | 4 | Name |
+----+--------------+------+------+----------+ +----+----------------+
My Table4
+----+------------+----------+
| ID | TicketName | FileName |
+----+------------+----------+
| 0 | T002 | Name |
| 1 | T002 | Name |
| 2 | T003 | Name |
| 3 | T004 | Name |
| 4 | T007 | Name |
+----+------------+----------+
My goal is to reach Select that looks like this
+----+--------------+----------------+--------------+----------+-----------+
| ID | TicketNumber | HowManyTickets | HowManyFiles | User | Admin |
+----+--------------+----------------+--------------+----------+-----------+
| 0 | T001 | 1 | 0 | UserName | AdminName |
| 1 | T002 | 2 | 2 | UserName | AdminName |
| 2 | T003 | 1 | 1 | UserName | AdminName |
| 3 | T004 | 5 | 1 | UserName | AdminName |
+----+--------------+----------------+--------------+----------+-----------+
Unfortunaly all i am capable of doing is either getting
TicketNumber, HowManyTickets, HowManyFiles,
or
TicketNumber, HowManyTickets, User, Admin
It seems your result ID is generated since its not anymore the same to your TicketID.
Here's my suggestion, using row_number() to generate the ID, then use sum() aggregation function to group your ticketNumber. left join will give you 0 result on your Ticket T001.
select row_number() over (order by t1.TicketNumber) as ID
, t1.TicketNumber
, sum(case when coalesce(t1.TicketNumber, '') = '' then 0 else 1 end) as HowManyTickets
, coalesce(t4.numFiles, 0) as HowManyFiles
, t2.Name as USER
, t3.Name as Admin
from table1 t1
left join table2 t2 on t2.ID = t1.ID_U
left join table3 t3 on t3.ID = t1.ID_A
left join
(select count(1) as numFiles, TicketNumber from table4 group by TicketNumber) t4 on t4.TicketNumber = t1.TicketNumber
group by t1.TicketNumber, t4.numFiles

SQL - How can I JOIN two tables and SUM a column based on IDs between them?

I have two tables. One table is with master data
Table tbl1:
+-------------+------------+------------+
| ID | Name | Total |
+-------------+------------+------------+
| 1 | a | 10 |
| 2 | b | 5 |
| 3 | c | 4 |
| 4 | a | 4 |
+-------------+------------+------------+
Second table tbl2 contains child data. The key between tables is ID
Table tbl2:
+-------------+------------+
|id | qty |
+-------------+------------+
| 1 | 4 |
| 1 | 3 |
| 1 | 1 |
| 3 | 1 |
| 3 | 3 |
+-------------+------------+
I need to get output like this:
Output:
+-------------+------------+------------+
| name | sum_tot | sum_qty |
+-------------+------------+------------+
| a | 14 | 8 |
| b | 5 | 0 |
| c | 4 | 4 |
+-------------+------------+------------+
I had tried with this:
select tbl1.name, SUM(tbl1.total), SUM(tbl2.qty)
from tbl1
left join tbl2 ON tbl1.id = tbl2.id
GROUP by tbl1.name
The output that I get is:
Output:
+-------------+------------+------------+
| name | sum_tot | sum_qty |
+-------------+------------+------------+
| a | 34 | 8 |
| b | 5 |null |
| c | 8 | 4 |
+-------------+------------+------------+
Which is not correct.
Here is the sql fiddle:
The summary from first table is not in relation with second table. It seems that somehow query runs three times.
You can simply have a correlated sub-query that calculates the tbl2 sum:
select tbl1.name,
SUM(tbl1.total),
SUM(COALESCE((select SUM(tbl2.qty)
from tbl2
where tbl1.id = tbl2.id), 0)) as qty_tot
from tbl1
GROUP by tbl1.name
SELECT A.name, SUM(A.total) as sum_tot, COALESCE(B.sum_qty, 0) as sum_qty
FROM tbl1 A
LEFT JOIN (
SELECT id, SUM(qty) as sum_qty
FROM tbl2
GROUP BY id
) B ON B.id = A.id
GROUP BY A.name
select tbl1.name, SUM(tbl1.total), SUM(COALESCE(tbl2.qty, 0))
from tbl1
left join tbl2 ON tbl1.id = tbl2.id
GROUP by tbl1.name

HAVING COUNT receiving other COUNT value

I'm working with a select in two different tables that should be match by group reference id, like:
Table 1 and table 2:
+-----+-----+------------+ +-----+------+
| gid | tid | created | | gid | nid |
+-----+-----+------------+ +-----+------+
| 0 | 816 | 1480002041 | | 0 | 1123 |
| 1 | 731 | 1480003932 | | 0 | 1124 |
| 1 | 736 | 1480003932 | | 1 | 1125 |
| 2 | 746 | 1480003932 | | 1 | 1126 |
+-----+-----+------------+ | 1 | 1123 |
| 2 | 1124 |
| 1 | 1129 |
+-----+------+
I need to get nid values from table 2 that have a exactly group match with the group on table 1. The reference to search in table 1 is tid.
I believe that the SQL would be something like that:
SELECT t1.nid
FROM table1 t1
INNER JOIN
(
SELECT gid
FROM table2
WHERE tid IN (731, 736, 746, 751)
GROUP BY gid
HAVING COUNT(DISTINCT tid) = 4
) t2 ON t1.gid = t2.gid;
But how can I get the exactly count to replace hard coded number 4?
SELECT t2.nid
FROM table1 t1
INNER JOIN
table2 t2
ON t1.gid = t2.gid;
WHERE t2.tid IN (731, 736, 746, 751)
GROUP BY t2.gid

MySQL - How to update atable based on an internal ordering of the table

If I make a selection from my MySQL table like:
SELECT * FROM mytable ORDER BY country_id, category
I get the following table:
+------------+----------+-------+
| country_id | category | order |
+------------+----------+-------+
| 1 | A | 0 |
| 1 | B | 0 |
| 1 | F | 0 |
| 3 | A | 0 |
| 3 | C | 0 |
| 5 | B | 0 |
| 5 | L | 0 |
| 5 | P | 0 |
+------------+----------+-------+
What I would like to do is update the order column so that the value of that column is the order of that row for it's country_id. In other words the final table should look like this:
+------------+----------+-------+
| country_id | category | order |
+------------+----------+-------+
| 1 | A | 1 |
| 1 | B | 2 |
| 1 | F | 3 |
| 3 | A | 1 |
| 3 | C | 2 |
| 5 | B | 1 |
| 5 | L | 2 |
| 5 | P | 3 |
+------------+----------+-------+
If I use the original query given at the top in a subquery, that would give me the correct order but I can't figure out how to iterate through the table and suspect I thinking about it wrongly.
How can I get this result?
Many thanks
Try to use this query -
UPDATE mytable t1
JOIN (
SELECT t1.country_id, t1.category, COUNT(*) `order`
FROM mytable t1
LEFT JOIN mytable t2
ON t2.country_id = t1.country_id AND t2.category <= t1.category
GROUP BY
t1.country_id, t1.category
) t2
ON t1.country_id = t2.country_id AND t1.category = t2.category
SET t1.`order` = t2.`order`
As an aside note, you can remove order field from the table because this can calculated this on the fly.

MySQL SELECT value before MAX

How to select 1st, 2nd or 3rd value before MAX ?
usually we do it with order by and limit
SELECT * FROM table1
ORDER BY field1 DESC
LIMIT 2,1
but with my current query I don't know how to make it...
Sample table
+----+------+------+-------+
| id | name | type | count |
+----+------+------+-------+
| 1 | a | 1 | 2 |
| 2 | ab | 1 | 3 |
| 3 | abc | 1 | 1 |
| 4 | b | 2 | 7 |
| 5 | ba | 2 | 1 |
| 6 | cab | 3 | 9 |
+----+------+------+-------+
I'm taking name for each type with max count with this query
SELECT
`table1b`.`name`
FROM
(SELECT
`table1a`.`type`, MAX(`table1a`.`count`) AS `Count`
FROM
`table1` AS `table1a`
GROUP BY `table1a`.`type`) AS `table1a`
INNER JOIN
`table1` AS `table1b` ON (`table1b`.`type` = `table1a`.`type` AND `table1b`.`count` = `table1a`.`Count`)
and I want one more column additional to name with value before max(count)
so result should be
+------+------------+
| name | before_max |
+------+------------+
| ab | 2 |
| b | 1 |
| cab | NULL |
+------+------------+
Please ask if something isn't clear ;)
AS per your given table(test) structure, the query has to be as follows :
select max_name.name,before_max.count
from
(SELECT type,max(count) as max
FROM `test`
group by type) as type_max
join
(select type,name,count
from test
) as max_name on (type_max.type = max_name.type and count = type_max.max )
left join
(select type,count
from test as t1
where count != (select max(count) from test as t2 where t1.type = t2.type)
group by type
order by count desc) as before_max on(type_max.type = before_max .type)