I know it can be done with union, but is kind of repetitive -- so is there a way to split multi column every row into multiple single column rows?
Example:
SPLIT(SELECT col1,col2,col3 FROM tbl);
SPLIT is my imaginary function, for:
SELECT col1 FROM tbl
UNION
SELECT col2 FROM tbl
UNION
SELECT col3 FROM tbl;
So, is there such UNION/SPLIT equivalent?
First, you should use union all -- unless you intend to incur the overhead to remove duplicates:
SELECT col1 FROM tbl
UNION ALL
SELECT col2 FROM tbl
UNION ALL
SELECT col3 FROM tbl;
The above requires scanning the table 3 times. You can scan the table just once using CROSS JOIN, but the logic is a little more cumbersome:
SELECT (CASE col WHEN 1 THEN col1 WHEN 2 THEN col2 WHEN 3 THEN col3 END) as col
FROM tbl CROSS JOIN
(SELECT 1 as col UNION ALL SELECT 2 UNION ALL SELECT 3) x;
I should note that other databases support unpivot and lateral joins, either of which can be used for this purpose. However, these constructs are not in MySQL.
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.
How can I rearrange a table to get a list of the existing combinations (in both directions) in Mysql?
For example, I have a table with two columns
col1 col2
1 5
7 1
1 2
I want to get a new table (added onto the existing table) where I flip col2 and col1.
col1 col2
1 5
7 1
1 2
5 1
1 7
2 1
This allows me to see all the values for each number, when looking both directions.
Like
1: 5, 2, 7
2: 1
5: 1
7: 1
Hopefully this makes sense.
Thanks for the help!
Use union.
select col1,col2 from tbl
union
select col2,col1 from tbl
union is used instead of union all because the latter would give duplicate rows when a symmetric pair already exists in the table (for example the combination 1,5 5,1)
Then use group_concat.
select col1,group_concat(col2)
from (select col1,col2 from tbl
union
select col2,col1 from tbl) t
group by col1
If you make use off a delivered table you don't have to create a new table.
And you can make use of one query instead of using two queries.
Query
SELECT
col1,
GROUP_CONCAT(col2) AS col2
FROM
(SELECT
col1, col2
FROM
[TABLE]
UNION
SELECT
col2, col1
FROM
[TABLE]
) table_data
GROUP BY
col1
ORDER BY
col1 ASC
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'
)
I have two tables with different columns. Tables doesn't have id column. They have the same number of rows. I want to merge them in new table. I've tried to do this like this:
CREATE TABLE test_3_cut_dest as
SELECT * FROM test_3_cut_
UNION
SELECT * FROM test_3_cut
but got error:
each UNION query must have the same number of columns
I want to know how achieve merging of two tables with different number of columns without specifying list of columns?
I don't think it works with select * when it comes to not knowing how many columns each table has. The best way to do it is like this:
SELECT A, B, C, D, E, F, G, H FROM test_3_cut_
UNION
SELECT A, B, NULL AS C, NULL AS D, NULL AS E, NULL AS ... FROM test_3_cut
I've done it like this considering test_3_cut has fewer columns than test_3_cut_
Union requires that all participating selects yield matching record sets, meaning same number of columns and compatible data types for each column.
As for your question, you can use placeholders wherever there is a mismatch. For instance:
SELECT Col1, Col2, 'DUMMYVALUE'
FROM Table1
UNION ALL
SELECT Col1, Col2, Col3
FROM Table2 ;
Now, if table1 has 3 textual columns and table2 has 6 textual columns, you can go with:
SELECT * , 'DUMMYVALUE1','DUMMYVALUE2','DUMMYVALUE3'
FROM Table1
UNION ALL
SELECT *
FROM Table2 ;
Union works like this:
Select column1 from table1
union
select column1 from table2
Number of columns must be same in both Select Queries.
You have to select from the two tables the same set of columns. If one of the tables has more columns, you can either select only the columns they share or select a fake value for the missing column from the table that has less.
Example
Table1
col1 | col2 | col3
Table2
col1 | col2
You can do this
select col1, col2 from Table1
union all
select col1, col2 from Table2
or this
select col1, col2, col3 from Table1
union all
select col1, col2, '' from Table2
I have a table with 53 columns (all integer types) and thousands of rows. I just want to be able to figure out how many times does a zero occur in each column . So the example output would be something like below :
Columns | Zero Counts
col1 2
col2 3
col3 2
col4 0
I've tried different queries though none fit in right . Would appreciate any help .
Somthing like this should work:
select 'col1', Count(*) from yourtable where col1=0
Union
select 'col2', Count(*) from yourtable where col2=0
Union
select 'col3', Count(*) from yourtable where col3=0
This will help you.
SELECT count(col1) FROM table_name WHERE col1=0
UNION
SELECT count(col2) FROM table_name WHERE col2=0