Get Data from Table with Column as Rows in MYSQL - mysql

Can any one help me with a query that converts column into rows and then find data accordingly.
The question is below. I have tried a query that gets the column names into rows but i was unable to get values or had any idea to figure it out for column3 and column 4. I am a new bibe in SQL. Can anyone help me out here. I heard from a friend suggesting pivot and when i browse i found PIVOT is not supported in MYSQL
Input Table:
E1 E2 E3 E4 E5 E6
Null 1234 234 12 A B
123 Null Null Null 12 B
Null Null Null Null Null Null
123 2 1 A 1 2
Output Table:
C1 C2 Count TotalC percent
E1 123 2 2 1
E2 1234 1 2 0.5
E2 2 1 2 0.5
E3 234 1 2 0.5
E3 1 1 2 0.5
E4 12 1 2 0.5
E4 A 1 2 0.5
E5 A 1 3 0.3
E5 12 1 3 0.3
E5 1 1 3 0.3
E6 B 2 3 0.6
E6 2 1 3 0.3
Explanation of the Question:
C1 is the Column names of input table.
C2 is the data in those columns.
Count is the number of similar items and singles in each columns.
TotalC is the number of total not null values.
percent is the count/totalc.
Query i worked : SELECT (COLUMN_NAME)AS Column1 FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = 'inputtable';
Note: query in MYSQL.

As mentioned in my comment above, you should probably handle this problem differently. See What is the XY problem?
However, if you must, you can solve this problem using UNION:
SELECT *, Count/TotalC AS percent
FROM (
SELECT 'E1' AS C1, E1 AS C2, COUNT(*) AS Count
FROM Input
WHERE E1 IS NOT NULL
GROUP BY C2
UNION ALL
SELECT 'E2' AS C1, E2 AS C2, COUNT(*) AS Count
FROM Input
WHERE E2 IS NOT NULL
GROUP BY C2
UNION ALL
SELECT 'E3' AS C1, E3 AS C2, COUNT(*) AS Count
FROM Input
WHERE E3 IS NOT NULL
GROUP BY C2
UNION ALL
SELECT 'E4' AS C1, E4 AS C2, COUNT(*) AS Count
FROM Input
WHERE E4 IS NOT NULL
GROUP BY C2
UNION ALL
SELECT 'E5' AS C1, E5 AS C2, COUNT(*) AS Count
FROM Input
WHERE E5 IS NOT NULL
GROUP BY C2
UNION ALL
SELECT 'E6' AS C1, E6 AS C2, COUNT(*) AS Count
FROM Input
WHERE E6 IS NOT NULL
GROUP BY C2
) t1 NATURAL JOIN (
SELECT 'E1' AS C1, COUNT(E1) AS TotalC FROM Input
UNION ALL
SELECT 'E2' AS C1, COUNT(E2) AS TotalC FROM Input
UNION ALL
SELECT 'E3' AS C1, COUNT(E3) AS TotalC FROM Input
UNION ALL
SELECT 'E4' AS C1, COUNT(E4) AS TotalC FROM Input
UNION ALL
SELECT 'E5' AS C1, COUNT(E5) AS TotalC FROM Input
UNION ALL
SELECT 'E6' AS C1, COUNT(E6) AS TotalC FROM Input
) t2
See it on sqlfiddle.

Related

Creating duplicate rankings with window function in mysql

I have a table like below:
product
country
group
value
p1
c1
g1
5
p1
c1
g2
6
p1
c2
g1
3
p1
c2
g2
22
p1
c3
g1
1
p1
c3
g2
6
I want to rank them considering the sum in value column for every product-country combination. So in this case, the updated table should be like this:
product
country
group
value
rank
p1
c1
g1
5
2
p1
c1
g2
6
2
p1
c2
g1
3
1
p1
c2
g2
22
1
p1
c3
g1
1
3
p1
c3
g2
6
3
p1-c1 combination will have the 2nd seed because 5+6 in the value column is higher than 7 (1+6) and lower than 25 (22+3). I used dense_rank() over (partition by product, country order by value) but it didn't work. How can I create the above ranking using mysql?
Thanks,
First use SUM() window function in a subquery to get the total value for each product, country combination and then DENSE_RANK() to rank the totals:
select product, country, `group`, value,
dense_rank() over (order by total desc) rnk
from (
select *, sum(value) over (partition by product, country) total
from tablename
) t
See the demo.

Delete duplicate elements in SQL

How to delete duplicate elements in SQL?
That is mean in each column, each element should only occur once.
For example, I have a table like:
NAME1 NAME2 NAME3 NAME4
A1 A2 A3 A4
A1 B2 A3 A4
A1 C2 C3 B4
B1 C2 B3 C4
C1 B2 A3 B4
There are so many duplicate elements in each column and they are placed randomly.
I should convert it to the table like below:
NAME1 NAME2 NAME3 NAME4
A1 A2 A3 A4
B1 B2 B3 B4
C1 C2 C3 C4
Well, I finally found out a solution to my problem.
Select the distinct names in each column as tables and then inner join them with adding common rownumbers could work.
However, this problem could be solved since the number of distinct names in each column are equal. I am still trying to find out how to solve the problem when the number of distinct names in each column are not equal.
set #r1 = 0, #r2=0, #r3=0, #r4=0;
select A.n1, B.n2, C.n3, D.n4 from
(select *,
case when n1 is not null then (#r1:=#r1+1) end as Rownumber
from(
select distinct NAME1 n1
from MYTABLE)Tn1)A
inner join
(select *,
case when n2 is not null then (#r2:=#r2+1) end as Rownumber
from(
select distinct NAME2 n2
from MYTABLE)Tn2)B
on A.Rownumber = B.Rownumber
inner join
(select *,
case when n3 is not null then (#r3:=#r3+1) end as Rownumber
from(
select distinct NAME3 n3
from MYTABLE)Tn3)C
on A.Rownumber = C.Rownumber
inner join
(select *,
case when n4 is not null then (#r4:=#r4+1) end as Rownumber
from(
select distinct NAME4 n4
from MYTABLE)Tn4)D
on A.Rownumber = D.Rownumber;

How can I get the result by only one sql in MySQL

There two mysql table just like table1 and table2. I want get the result by one sql.
#table1
c1 c2 //clomun
a 10
b 20
c 30
#table2
c1 c2
a 11
b 21
e 99
I want get the result like below.
# result
c1 c2
a 21
b 41
c 30
e 99
This should work:
select c1, sum(c2) from
(
select c1, c2 from table1
union all
select c1, c2 from table2
) as total
group by c1
Please note that if the columns names are not identical, you will need to give them identical alias names as below:
select column1, sum(column2 ) from
(
select c1 as column1, c2 as column2 from table1
union all
select c1 as column1, c2 as column2 from table2
) as total
group by column1

Find average of rows over name ;display all rows

I have a table with the below values
name symbol current value
a a1 1
a a2 2
a a3 4
a a4 3
a a5 5
b b1 6
b b2 7
b b3 8
c c1 1
c c2 2
c c3 3
c c4 3
c c5 5
d d1 6
d d2 6
Required : To find the average of the current value grouping by name , yet show all results . ie ; the result show be like below ;
name symbol current value Required
a a1 1 =current value/(sum of all 'a' current values)
a a2 2 =current value/(sum of all 'a' current values)
a a3 4 =current value/(sum of all 'a' current values)
a a4 3 =current value/(sum of all 'a' current values)
a a5 5 =current value/(sum of all 'a' current values)
b b1 6 = current value /(sum of all 'b' current values)
b b2 7 = current value /(sum of all 'b' current values)
b b3 8 = current value /(sum of all 'b' current values)
Similarly for all names
Join to a subquery which finds the averages:
SELECT t1.*,
CASE WHEN t2.avg > 0 THEN t1.current_value / t2.avg ELSE 0 END AS avg
FROM yourTable t1
INNER JOIN
(
SELECT name, SUM(current_value) AS avg
FROM yourTable
GROUP BY name
) t2
ON t1.name = t2.name;
The CASE expression is necessary to protect against a possible divide by zero, which could happen if a given name happen to have all zero current values. In that case, I default the average to zero.
try this logic :)
SELECT
*
FROM
table_listing_sample
WHERE
NAME = 'a'
AND NAME = 'b'
ORDER BY
id

SQL select rows having count > certain number

I don't really know how to search for this, probably it's quite easy to do it, but I don't know how to do this.
I have a SQL table:
| c1 | c2 | c3 | c4 | c5 |
data data data data data
So I've 5 columns, and now I want to select the rows with only the following (c1, c2, c3) where that row appears more than 5 times in the table
Something like this:
Select c1, c2, c3
From table
having count(*) > 5 and (all in that count, all rows must have the same values on c1, c2, c3)
Can only do this with basical sql queries. Functions, declarations and etc are not allowed.
Don't really know if i'm explaining myself well.
Not absolutely sure I understand, but my guess would be
select c1, c2, c3
from <yourtable>
group by c1, c2, c3
having count(*) > 5
This query will return all records from your original table whose c1, c2, and c3 combined values appear in duplicate more than 5 times. I also included the actual count in the result set.
SELECT t1.c1, t1.c2, t1.c3, t1.c4, t1.c5, t2.cardinality
FROM yourTable t1
INNER JOIN
(
SELECT c1, c2, c3, COUNT(*) AS cardinality
FROM yourTable
GROUP BY c1, c2, c3
HAVING COUNT(*) > 5
) t2
ON t1.c1 = t2.c1 AND
t1.c2 = t2.c2 AND
t1.c3 = t2.c3
Just treat c1,c2,c3 as a single string c1+c2+c3:
SELECT c1, c2, c3 FROM table WHERE
c1 || c2 || c3 IN (
SELECT c1 || c2 || c3 FROM table
GROUP BY c1 || c2 || c3
HAVING COUNT(*) > 5);