SO I have a table with 3 cols:
Col1 Col2 Col3
a b c
b c null
a null b
c d a
And my desired output will be:
a,b,c,d,null
I am hoping to have the output in a single string if possible.
I have tried:
SELECT DISTINCT col1, col2, col3 FROM table
and didn't get the desired results. Any Ideas?
A single-string solution (see on sqlfiddle):
SELECT GROUP_CONCAT(COALESCE(c, 'NULL'), ',')
FROM (
SELECT col1 c
FROM mytable
UNION
SELECT col2 c
FROM mytable
UNION
SELECT col3 c
FROM mytable
) q
SELECT Col1
FROM table
UNION
SELECT Col2
FROM table
UNION
SELECT Col3
FROM table
does this work in sqlite:
select col1 from table
union
select col2 from table
union
select coll3 from table
or:
select col1 from table where col1 is not null
union
select col2 from table where col2 is not null
union
select coll3 from table where col3 is not null
to eliminate nulls.
Note i don't think this would be fast to execute but I know in mssql union will do a distinct on the results
If you are using MySql, you could use this solution:
select group_concat(coalesce(c,'null') order by c is null, c)
from (
select col1 c from tbl
union
select col2 c from tbl
union
select col3 c from tbl
) u
Union query selects all values, removing all duplicates. I'm then returning the result in a single string, ordered by value with null value at the end, and converting null to 'null' (since group_concat would ignore null values).
If you are using SQLite, Group_Concat doesn't support order by, and you could use this:
select group_concat(coalesce(c,'null'))
from (
select col1 c, col1 is null o from mytable
union
select col2 c, col2 is null o from mytable
union
select col3 c, col3 is null o from mytable
order by o, c
) u
Related
Suppose I have data containing two columns I am interested in. Ideally, the data in these is always in matching sets like this:
A 1
A 1
B 2
B 2
C 3
C 3
C 3
However, there might be bad data where the same value in one column has different values in the other column, like this:
D 4
D 5
or:
E 6
F 6
How do I isolate these bad rows, or at least show that some of them exist?
You can use exists:
select t.*
from t
where exists (select 1 from t t2 where t2.col1 = t.col1 and t2.col2 <> t.col2);
If you just want the col1 values that have non-matches, you can use aggregation:
select col1, min(col2), max(col2)
from t
group by col1
having min(col2) <> max(col2);
Using MIN and MAX as analytic functions we can try:
WITH cte AS (
SELECT t.*, MIN(col2) OVER (PARTITION BY col1) AS min_col2,
MAX(col2) OVER (PARTITION BY col1) AS max_col2
FROM yourTable t
)
SELECT col1, col2
FROM cte
WHERE min_col2 <> max_col2;
The above approach, while seemingly verbose, would return all offending rows.
I want to add a UNIQUE index to a table, like this:
ALTER TABLE `mytable` ADD UNIQUE `myunique_name`(`first`, `second`, `third`);
Mysql responds with:
Duplicate entry '1-2-3' for key 'myunique_name'
I know for sure that this combination is just one out of thousands that violate the constraint.
In this special case I know for sure that all the rows that contain the same values in the three specified columns also contain the same data in the other relevant fields (the primary index differs of course, but is irrelevant), therefore all the duplicates can be deleted.
Is there a way to do delete all duplicate entries but keep one (doesn't matter which primary key is kept) so that the unique index can be added?
CREATE TEMPORARY TABLE IF NOT EXISTS MyTable engine=memory
select 1 as id, 1 col1,1 col2,1 col3
union all
select 2 as id, 2 col1,2 col2,2 col3
union all
select 3 as id, 3 col1,3 col2,3 col3
union all
select 4 as id, 4 col1,4 col2,4 col3
union all
select 5 as id, 1 col1,1 col2,1 col3
union all
select 6 as id, 2 col1,2 col2,2 col3
CREATE TEMPORARY TABLE IF NOT EXISTS MyDuplicateTableWithCount engine=memory
select col1 , col2 , col3, count(*) Count_1
from MyTable
group by col1 , col2 , col3
having count(*)>1
select a.* from MyTable a
inner join
(select col1 , col2 , col3
from MyDuplicateTableWithCount
) b
on a.col1 =b.col1 and a.col2 =b.col2 and a.col3 =b.col3
order by a.id
After getting the duplicate id's write your delete query specifyinging duplicate id's as
delete from myTable where id in (5,6)
Also use below query using myTable from above
CREATE TEMPORARY TABLE IF NOT EXISTS MyTable2 engine=memory
SELECT MIN(id) as id, Col1, Col2, Col3
FROM MyTable
GROUP BY Col1, Col2, Col3
DELETE a FROM MyTable as a
LEFT JOIN (
SELECT * from MyTable2
) as b ON
b.id = a.id
WHERE
b.id IS NULL
Probably a big Title! sorry for that.. :(
Table 1
id col1 col2
1 10 one
2 11 two
3 10 three
Now, i would like to write a sql query to get distinct col1 from table1 which doesn't have three in col2. I need the output col1 - 11 only.
I tried like this select distinct col1 from table1 where col2 != 'three' but this gives the result as both 10 and 11. But for 10 it has corresponding row with three as col2 value. Kindly help me to find this.
Use group by and having.
select col1
from table1
group by col
having sum(case when col2='three' then 1 else 0 end)=0
If you are using MySQL, the having condition can be shortened to
select col1
from table1
group by col
having sum(col2='three')=0
as conditions are treated as booleans returning 1 for true and 0 for false.
using not in()
select distinct col1
from table1 t
where col1 not in (
select col1
from table1 i
where i.col2 = 'three'
)
or using not exists()
select distinct col1
from table1 t
where not exists (
select 1
from table1 i
where i.col1 = t.col1
and i.col2 = 'three'
)
Here is my sample table
Col1 Col2
A A
B B
A C
B D
C C
I want to be able to select distinct records where all rows have the same value in Col1 and Col2. So my answer should be
Col1 Col2
A A
B B
C C
Simply:
select distinct * from t where col1 = col2;
if both cols have null and you want to get that row too:
select distinct * from t where coalesce(col1, col2) is null or col1 = col2;
The query is already written in your request:
select distinct records where all rows have the same value in Col1 and Col2
SELECT DISTINCT *
FROM tbl
WHERE Col1 = Col2
How do I structure my query so I can count how many occurrences of a value in column 1 appears in column 2 and then store that result in a new column in the same table? (If a value is duplicated in the first column I still want to store the same value in the new column) For example if I had a table like this:
COL1 COL2
1 2
1 4
2 1
3 1
4 1
4 2
The resulting table will look like this:
COL1 COL2 COL3
1 2 3
1 4 3
2 1 2
3 1 0
4 1 1
4 2 1
Any help is appreciated I am new to sql! Thanks in advance!
Select
col1,
col2,
COALESCE(col3,0) as col3
FROM
mytable
LEFT JOIN
( Select count(*) as col3, col2
from mytable
GROUP BY col2) as temp ON temp.col2 = mytable.col1
And if you want the update (thanks Thorsten Kettner ) :
UPDATE mytable
LEFT JOIN ( Select count(*) as col3, col2
from mytable
GROUP BY col2) as temp ON temp.col2 = mytable.col1
SET mytable.col3 = COALESCE(temp.col3,0)
You can easily count on-the-fly. Don't store this redundantly. This would only cause problems later.
select
col1,
col2,
(
select count(*)
from mytable match
where match.col2 = mytable.col1
) as col3
from mytable;
If you think you must do it; here is the according UPDATE statement:
update mytable
set col3 =
(
select count(*)
from mytable match
where match.col2 = mytable.col1
);
To do that, you can try :
SELECT COL1, COL2, (SELECT COUNT(COL1) FROM `tablename` AS t2
WHERE t2.COL1 = t1.COL1) AS COL3 FROM `tablename` AS t1
Enjoy :)