Cannot figure a simple mysql query out - mysql

I feel very very stupid now because I have a problem and cannot seem to figure it out.
Very simple MySQL table with 2 columns :
ID1 | ID2
1 | 1
1 | 2
2 | 1
Don't know very good how to explain the conditions : I want to select the value 1 from the column ID1 because it has connections with the values 1 AND 2 from ID2.
It's somewhat the opposite of IN.
If I make
SELECT ID1 FROM X WHERE ID2 IN (1,2) I recieve both 1 and 2 because it is a reunion. I want an intersection, something like SELECT ID1 FROM X WHERE ID2 IN BOTH 1 AND 2.
I am fairly sure it has something to do with grouping.
1 solution is to make
SELECT * FROM
(SELECT ID1, GROUP_COCAT(ID2) y
FROM X
GROUP BY ID1)t
WHERE t.y = '1,2'
but this is NOT ok because I do not know the order ( 1,2 or 2,1 ) and I can have more values.
Hopefully this is clear enough, I am very tired.

SELECT t.*
FROM TEMP t
WHERE t.id2 IN (1, 2)
GROUP BY t.id1 HAVING COUNT(*) = 2
OR
SELECT t.*
FROM TEMP t
WHERE t.id2 IN (1, 2, 3, 4)
GROUP BY t.id1 HAVING COUNT(*) = 4

Related

Select duplicates while concatenating every one except the first

I am trying to write a query that will select all of the numbers in my table, but those numbers with duplicates i want to append something on the end that shows it as a duplicate. However I am not sure how to do this.
Here is an example of the table
TableA
ID Number
1 1
2 2
3 2
4 3
5 4
SELECT statement output would be like this.
Number
1
2
2-dup
3
4
Any insight on this would be appreciated.
if you mysql version didn't support window function. you can try to write a subquery to make row_number then use CASE WHEN to judgement rn > 1 then mark dup.
create table T (ID int, Number int);
INSERT INTO T VALUES (1,1);
INSERT INTO T VALUES (2,2);
INSERT INTO T VALUES (3,2);
INSERT INTO T VALUES (4,3);
INSERT INTO T VALUES (5,4);
Query 1:
select t1.id,
(CASE WHEN rn > 1 then CONCAT(Number,'-dup') ELSE Number END) Number
from (
SELECT *,(SELECT COUNT(*)
FROM T tt
where tt.Number = t1.Number and tt.id <= t1.id
) rn
FROM T t1
)t1
Results:
| id | Number |
|----|--------|
| 1 | 1 |
| 2 | 2 |
| 3 | 2-dup |
| 4 | 3 |
| 5 | 4 |
If you can use window function you can use row_number with window function to make rownumber by Number.
select t1.id,
(CASE WHEN rn > 1 then CONCAT(Number,'-dup') ELSE Number END) Number
from (
SELECT *,row_number() over(partition by Number order by id) rn
FROM T t1
)t1
sqlfiddle
I made a list of all the IDs that weren't dups (left join select) and then compared them to the entire list(case when):
select
case when a.id <> b.min_id then cast(a.Number as varchar(6)) + '-dup' else cast(a.Number as varchar(6)) end as Number
from table_a
left join (select MIN(b.id) min_id, Number from table_a b group by b.number)b on b.number = a.number
I did this in MS SQL 2016, hope it works for you.
This creates the table used:
insert into table_a (ID, Number)
select 1,1
union all
select 2,2
union all
select 3,2
union all
select 4,3
union all
select 5,4

SQL Query - Find Duplicates with a Different Key

I have the following data:
id userid name group
1 1 A x
2 1 A y
3 1 A z
4 2 B x
5 2 B y
6 3 C y
7 4 D x
8 5 E x
9 5 E z
10 6 F x
I want to find those records that meet all this condition:
Select all rows where the a userid belongs to a group other than y but the userid also belongs to group y.
The resulting dataset will be as follows:
id userid name group
1 1 A x
3 1 A z
4 2 B x
If you see, it has resulted in two records for userid a because these are two two records belong to groups other than y but the userid 1 also belongs to group y. Same for userid 2.
I have been breaking my head on how to get this in an SQL statement but not even close to a solution.
Any help is appreciated.
Use a join:
SELECT t1.*
FROM mytable t1
INNER JOIN mytable t2
ON t1.user_id = t2.user_id AND t1.group <> t2.group AND t2.group = 'y'
I think that would be the fastest query (but please feel free to try the other solutions as well).
Add an index on user_id if not already there and maybe play with some other indexes as well (maybe a composite index on group and user_id can be utilized)
Use exists
select *
from MyTable a2
where name_group <> 'y'
and exists (select 1
from MyTable a2
where a2.name_group = 'y'
and a2.userid = a1.userid)
You can get all the users that meet the condition using aggregation and having:
select userid
from t
group by userid
having sum( group = 'y' ) > 0 and
sum( group <> 'y') > 0;
I leave it to your to put this into a query to get all the original rows.

Get Duplicated Count Without Removing

I am trying to get duplicate counts but without actually removing duplicates.
I tried using GROUP BY id and then COUNT(id) but it removes all duplicate entries.
Is there any way to not remove duplicates?
The table looks like this:
ID1 ID2 Value
1 2 someval
1 3 someval
1 4 someval
2 3 someval
2 1 someval
3 1 someval
4 1 someval
I am trying to get this:
ID1 ID2 Value COUNT
1 2 someval 3
1 3 someval 3
1 4 someval 3
2 3 someval 2
2 1 someval 2
3 1 someval 1
4 1 someval 1
I used this:
SELECT ID1, ID2, Value, COUNT(ID1) FROM table GROUP BY ID1;
One of way doing this is to have a separate query for the count and join on it:
SELECT t.id1, t.id2, t.value, cnt
FROM my_table t
JOIN (SELECT id1, count(*) AS cnt
FROM my_table
GROUP BY id1) c ON t.id1 = c.id1
You can do this with a correlated subquery in MySQL;
select id1, id2, value,
(select count(*) from table t2 where t2.id1 = t.id1) as count
from table t;
If performance is an issue then an uncorrelated subquery will likely be orders of magnitude faster than a correlated one...
SELECT x.*
, cnt
FROM my_table x
JOIN
( SELECT id1,COUNT(*) cnt FROM my_table GROUP BY id1) y
ON y.id1 = x.id1;
try something like this :
SELECT YourColumn, COUNT(*) TotalCount
FROM YourTable
GROUP BY YourColumn
HAVING COUNT(*) > 1
ORDER BY COUNT(*) DESC

Count Duplicates with same id passing in one coulmn

Hi there m trying to calculate the row count for same value,
id,value
1 | a
2 | b
3 | c
4 | d
5 | e
and my query is
select value, count(*) as Count from mytable where id in('4','2','4','1','4') group by value having count(*) > 1
for which my expected output will be,
value,Count
d | 3
b | 1
a | 1
Thanks, any help will be appreciated
Try that:
SELECT value, count(value) AS Count
FROM mytable m
WHERE value = m.value
GROUP BY value
SELECT t.id, t.value, COUNT(t.id)
FROM
test t
JOIN
( SELECT 1 AS id
UNION ALL SELECT 3
UNION ALL SELECT 3
UNION ALL SELECT 4
UNION ALL SELECT 1
UNION ALL SELECT 1 ) AS tmp
ON t.id = tmp.id
GROUP BY t.id
Sample on sqlfiddle.com
See also: Force MySQL to return duplicates from WHERE IN clause without using JOIN/UNION?
Of course, your IN parameter will be dynamic, and thus you will have to generate the corresponding SQL statement for the tmp table.
That's the SQL-only way to do it. Another possibility is to have the query like you have it in your question and afterwards programmatically associate the rows to the count passed to the IN parameter.

MySQL multiple values on own columns

I have a table like so;
id1 id2
1 1
2 1
1 2
3 2
1 3
4 3
1 4
5 4
I'd like to select it in a way that I'd get rows GROUPed by id2, but still preserving both values of id1 for the corresponding rows in the table.
So I'd get a result set like so;
id1 id1 id2
1 2 1
1 3 2
1 4 3
1 5 4
I've never been even half good in advanced database queries -- how would I go about achieving this?
If you have exactly 2 rows (with 2 values for id1) for every different value of id2, you can use this:
SELECT MIN(id1) AS id1_a
, MAX(id1) AS id1_b
, id2
FROM tableX
GROUP BY id2 ;
You could try using
SELECT id2, GROUP_CONCAT(id1) FROM your_table
GROUP BY id2
This way you have, for each id2 value, a column with all id1 values comma separated.
Take a look at GROUP_CONCAT syntax.
This might not be the perfect solution but in your case, it should work. This is a trick I used.
select id1, (sum(id1) - id1 ) as nID1, id2 from table_name group by id2
Hope it works.
Ujjwal