How to select values that already exists in column - mysql

I need to select all rows by value that posted more than one time.
Table:
key | value
------------
key1 | value
key2 | value
key2 | value
key3 | value
key3 | value
key4 | value
I need result like:
key2 | value
key3 | value

The below should get you what you need.
select key
from table
group by key
having count(*) > 1;

To find "duplicate" values of key, along with one of the values of value:
SELECT t.key
, MAX(t.value)
FROM mytable t
GROUP BY t.key
HAVING COUNT(1) > 1
To get (key,value) tuples that have "duplicates" in the table:
SELECT t.key
, t.value
FROM mytable t
GROUP
BY t.key
, t.value
HAVING COUNT(1) > 1

Related

MYSQL: Merge datas with same id and put all the datas to another new column

Good day,
I have a problem regarding how to build my query in MYSQL.
I have this raw data.
ID | NAME | VALUE | DESCRIPTION
ID-0001 | ARV1 | 10200 | First description
ID-0002 | ARV2 | 10300 | Second description
ID-0001 | ARV1 | 10400 | Added Description
And I want to achieve an output like this:
Where I want to merge the datas with the same ID and put the other tables in another column and with new column name.
ID | NAME | VALUE 1 | DESCRIPTION 1 | VALUE 2 | DESCRIPTION 2 |
ID-0001 | ARV1 | 10200 | First description | 10400 | Added Description |
ID-0002 | ARV2 | 10300 | Second description | | |
I badly need help. Thanks!
ID wise row is serialized as per storing data in DB that's why ORDER BY is not use. This query is alternative of PIVOT. But if more row exists for a same ID then PIVOT is better option. If any primary key is existed in table then use that PK at ORDER BY clause after PRTITION BY.
-- MySQL (v5.8)
SELECT t.id
, MAX(t.name) name
, MAX(CASE WHEN t.row_num = 1 THEN value END) value1
, MAX(CASE WHEN t.row_num = 1 THEN description END) description1
, MAX(CASE WHEN t.row_num = 2 THEN value END) value2
, MAX(CASE WHEN t.row_num = 2 THEN description END) description2
FROM (SELECT *
, ROW_NUMBER() OVER (PARTITION BY id) row_num
FROM test) t
GROUP BY t.id;
Please check from url https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=e4a5999a3536b9e042d7ed92fc392de7
Suppose table have a primary key column name p_id. Then ROW_NUMBER() will
ROW_NUMBER() OVER (PARTITION BY id ORDER BY p_id) row_num
N.B: By default p_id sorts the data in ascending order but if need descending order then use DESC.
WITH
cte AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY ID, NAME ORDER BY rowid) rn
FROM test
)
SELECT t1.ID, t1.NAME,
t1.VALUE value1, t1.DESCRIPTION description1,
t2.VALUE value2, t2.DESCRIPTION description2
FROM cte t1
LEFT JOIN cte t2 ON t1.ID = t2.ID
AND t1.NAME = t2.NAME
AND t2.rn = 2
WHERE t1.rn = 1;
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=e10ac4664ef614300c23a987f83e805d
PS. If a column which defines the rows priority not exists (rowid in the fiddle - it can be, for example, the creation datetime or something else) then the data order of the values pairs is not determined.

Select IDs from table where col_2 is not null (duplicate id)

I have a table that contains the following data
ID | Col_2
A | 'ABC'
A | 'GHI'
A | null
B | 'null'
B | 'HJH'
B | 'NBN'
C | null
I have two cases to cater :
Duplicate Ids:
Incase of duplicate ids I only want those IDs which do not have null in col_2
E.g.
Query should return :
A | 'ABC'
A | 'GHI'
B | 'HJH'
B | 'NBN'
Non Duplicate Id:
Incase of non duplicate id the query should return result irrespective of the value present in col_2
So the final result of the query should be
ID | Col_2
A | 'ABC'
A | 'GHI'
B | 'HJH'
B | 'NBN'
C | null
I have managed to create the following query where it is fulfilling the duplicate id case not the non duplicate case.
Query :
select id,col_2
from mytable
group by id,col_2
having (sum(case when col_2 is not null then 1 else 0 end) > 0)
What changes should be made in the query to cater the non duplicate case also.
Thanks in advance!!!
Assuming NULL is NULL and not a string and that you have only one NULL value per id, you can do something like this:
select t.*
from t
where t.col_2 is not null or
not exists (select 1 from t t2 where t2.id = t.id and t2.col_2 is not null);
If your null values can be duplicated and you want only one row for them, then tweak this to:
select t.*
from t
where t.col_2 is not null
union all
select distinct t.*
from t
where not exists (select 1 from t t2 where t2.id = t.id and t2.col_2 is not null);
Here is a db<>fiddle.
For performance, you want an index on (id, col_2).
If you just want the col_2 values for each id, you can concatenate them on each row:
select id, group_concat(col_2)
from t
group by id;
Another alternative uses window functions:
select t.id, col_2
from (select t.*,
rank() over (partition by id order by col_2 is not null desc) as seqnum
from t
) t
where seqnum = 1;

Find Values between two different columns in a table

table one
+----------------------+
|column A | Column B|
| 2 | 4 |
| 3 | 5 |
| 1 | 2 |
| 1 | 2 |
| 8 | 7 |
+----------------------+
Output
+-------+
|1 | 2 |
|1 | 2 |
+-------+
i want to print only the above output without COUNT, and any duplicate record example? please help
how about below where cluase
select * from t where columnA=1 and columnB=2
or
select columnA,columnB from t
group by columnA,columnB
having count(*)>1
or you can use exists
select t1.* from t t1 where exists
(select 1 from t t2 where t2.columnA=t1.columnA
and t2.columnB=t1.columnB group by columnA,columnB
having count(*)>1
)
You possibly want only those rows which are duplicate. If you don't have Window Functions available in your MySQL version, you can do the following:
SELECT
t.*
FROM your_table AS t
JOIN (SELECT columnA, columnB
FROM your_table
GROUP BY columnA, columnB
HAVING COUNT(*) > 1) AS dt
ON dt.columnA = t.columnA AND dt.columnB = t.columnB
Details: In a Derived table, we get all those combination of columnA and columnB which have more than one row(s) (HAVING COUNT(*) > 1).
Now, we simply join this result-set back to the main table, to get those rows only.
Note: This approach would not be needed if you want to fetch only these two columns. A simple Group By with Having would suffice, as suggested in other answer(s). However, if you have more columns in the table, and you will need to fetch all of them, and not just the columns (used to determine duplicates); you will need to use this approach.
You can use in operator with a grouped subquery as :
select *
from tab
where ( columnA, columnB) in
(
select columnA, count(columnA)
from tab
group by columnA
);
or use a self-join as :
select t1.columnA, t1.columnB
from tab t1
join
(
select columnA, count(columnA) as columnB
from tab
group by columnA
) t2
on ( t1.columnA = t2.columnA and t1.columnB = t2.columnB );
Rextester Demo
I would use EXISTS, if the table has primary column :
SELECT t.*
FROM table t
WHERE EXISTS (SELECT 1 FROM table t1 WHERE t1.col1 = t.col1 AND t1.col2 = t.col2 AND t1.pk <> t.pk);

MySQL: Retrieve Values and Counts For Each

How can I count the occurrence of the field/column in SQL?
Example dataset:
A
A
A
A
B
B
C
I want:
A | 4
A | 4
A | 4
A | 4
B | 2
B | 2
C | 1
Is there anyway to do it without using GROUP BY? So far all answer I get my query retuns the following:
A | 4
B | 2
C | 1
select value, count(*) from table group by value
Use HAVING to further reduce the results, e.g. only values that occur more than 3 times:
select value, count(*) from table group by value having count(*) > 3
You could use a nested sub-select for this desired result set.
If the example table name is my_table and the column called col1:
select col1,
(select count(*) from my_table where col1 = t.col1) as Count
from my_table t;
Or if you want to remove the duplicates, use the distinct statement. It removes the duplicates of your result set.
select distinct col1,
(select count(*) from my_table where col1 = t.col1) as Count
from my_table t;

MYSQL Updating row to maximum value of similar rows

I have a table like this in MYSQL:
ID | NAME | VALUE |
----------------------------
1 | Bob | 1 |
2 | Bob | 2 |
3 | Jack | 5 |
4 | Jack | 8 |
5 | Jack | 10 |
and I'm trying to update the VALUE column to the highest value of rows with same NAME. So the result should be:
ID | NAME | VALUE |
----------------------------
1 | Bob | 2 |
2 | Bob | 2 |
3 | Jack | 10 |
4 | Jack | 10 |
5 | Jack | 10 |
I managed to get the max value like this:
SELECT MAX(Value) max FROM `table` GROUP BY Name having count(*) >1 AND MAX(Value) != MIN(Value)
But can't figure out how to put it in my update
Update table set Value = (SELECT MAX(Value) max FROM `table` GROUP BY Name having count(*) >1 AND MAX(Value) != MIN(Value))
Doesn't work. I'd appreciate any help.
This is easier than other answers are making it.
UPDATE MyTable AS t1 INNER JOIN MyTable AS t2 USING (Name)
SET Value = GREATEST(t1.Value, t2.Value);
You don't have to find the largest value. You just have to join each row to the set of rows with the same name, and set the Value to the greater Value of the two joined rows. This is a no-op on some rows, but it will apply to every row in turn.
http://sqlfiddle.com/#!9/f79a3/1
UPDATE t1
INNER JOIN (SELECT name, MAX(`value`) max_value
FROM t1 GROUP BY name) t2
ON t1.name = t2.name
SET t1.value = t2.max_value;
Create a temporary table consisting of ID NAME and MAX VALUE as follows:
CREATE TEMP TABLE TABLE1 AS
(SELECT NAME,MAX(Value) value FROM `table` GROUP BY Name having count(*) >1
AND MAX(Value) != MIN(Value)
);
Use this temporary table to do your update as follows:
UPDATE
Table_A
SET
Table_A.value = Table_B.value
FROM
`table` AS Table_A
INNER JOIN TABLE1 AS Table_B
ON Table_A.NAME = Table_B.NAME
Also this code is somewhat of an approximation as i am not familiar with mysql but i am familiar with sql.
Let me know if this doesn't help.
Simple left join would do the trick.
Try this out and let me know in case of any queries.
select a.id,a.name,b.value
from
table a
left join
(select name,max(value) as value from table group by name) b
on a.name=b.name;
You may use this query. The table is joined with a subquery (table t2) that contains the results you want to update your table with:
UPDATE `table` t1,
(SELECT Name, MAX(Value) maxv, MIN(Value) minv
FROM `table`
GROUP BY Name
HAVING COUNT(*)>1 AND maxv != minv) t2
SET t1.Value = t2.maxv
WHERE t1.Name = t2.Name;
If you want to know how will the values be updated, you can first run an equivalent SELECT query:
SELECT t1.*, t2.maxv
FROM `table` t1,
(SELECT Name, MAX(Value) maxv, MIN(Value) minv
FROM `table`
GROUP BY Name
HAVING COUNT(*)>1 AND maxv != minv) t2
WHERE t1.Name = t2.Name;
This query will display all the fields of table, followed by the new value maxv. You can check the current value and the new value, and if it looks fine, you may run the UPDATE query.