How to make crosstab query in mysql - mysql

I'm using MySQL. This is table i have
Level Programmingtime Clientname projectid
0 128 abc 3
1 32 abc 3
2 126 abc 3
3 541 abc 3
4 452 abc 3
1 32 abc 3
But now i have to show this data in crystal report in such a format like
projectid level0 level1 level2 level3 level4
3 128 32+32=(64) 126 541 452
(programmingtime)
Please tell me what will be the my syntax for such a difficult logic.
Thanks in advance.

Since the levels are known, you can simply do:
SELECT
projectid,
SUM(CASE WHEN level = 0 THEN programmingtime ELSE 0 END) AS level0,
SUM(CASE WHEN level = 1 THEN programmingtime ELSE 0 END) AS level1,
SUM(CASE WHEN level = 2 THEN programmingtime ELSE 0 END) AS level2,
SUM(CASE WHEN level = 3 THEN programmingtime ELSE 0 END) AS level3,
SUM(CASE WHEN level = 4 THEN programmingtime ELSE 0 END) AS level4
FROM
tbl
GROUP BY
projectid

Related

SQL convert columns in rows

I want convert this table (Reading):
ID TimeTable_ID reading_Value Sensor_ID
1 1 482 1
2 1 153 2
3 1 152 3
4 1 781 4
5 2 156 1
6 2 842 2
7 2 157 3
8 2 453 4
into this:
TimeTable_ID Sensor_1 Sensor_2 Sensor_3 Sensor_4
1 482 153 152 781
2 156 842 157 453
My try:
SELECT *
FROM (SELECT TimeTable_ID, reading_Value
FROM Reading
) AS BaseData PIVOT
(COUNT(reading_Value) FOR TimeTable_ID IN ([Sensor_1], [Sensor_2], [Sensor_3], [Sensor_4])
) AS PivotTable;
but it does not work.
MySQL does not support the PIVOT operator. But, you may use a standard pivot query instead:
SELECT
TimeTable_ID,
MAX(CASE WHEN Sensor_ID = 1 THEN reading_Value END) AS Sensor_1,
MAX(CASE WHEN Sensor_ID = 2 THEN reading_Value END) AS Sensor_2,
MAX(CASE WHEN Sensor_ID = 3 THEN reading_Value END) AS Sensor_3,
MAX(CASE WHEN Sensor_ID = 4 THEN reading_Value END) AS Sensor_4
FROM Reading
GROUP BY TimeTable_ID;
If you have limited Sensors then you can do :
select TimeTable_ID,
sum(case when Sensor_ID = 1 then reading_Value else 0 end) as Sensor_1,
. . .
sum(case when Sensor_ID = 4 then reading_Value else 0 end) as Sensor_4
from reading r
group by TimeTable_ID;

Counting number of '1' values in each bit position in Redshift column

I have BIGINT column in my Redshift table, and I want a query that will:
Count how many times the value '1' appears in each bit position across the binary value in all the rows of this column
Will show it in a way that I'll be able to take the x top bits_positions.
For example (I'm already writing the integer values as binary to simplify the example):
column
--------
11011110 = 222
00000000 = 0
11111100 = 252
00011000 = 24
11111100 = 252
00011000 = 24
11000010 = 194
76543210 <- bit_position
will return a table like:
bit_position count
0 0
1 2
2 3
3 5
4 5
5 2
6 4
7 4
In this case I'll be able to get the top five bit_position: (3,4,6,7,2)
Note: I'll might have up to 64 bit_positions for a column.
You can use a bit-wise AND & to check for each position.
Here's an example going across rows:
SELECT SUM(CASE WHEN bit_col & 64 > 0 THEN 1 ELSE 0 END) "1000000"
, SUM(CASE WHEN bit_col & 32 > 0 THEN 1 ELSE 0 END) "0100000"
, SUM(CASE WHEN bit_col & 16 > 0 THEN 1 ELSE 0 END) "0010000"
, SUM(CASE WHEN bit_col & 8 > 0 THEN 1 ELSE 0 END) "0001000"
, SUM(CASE WHEN bit_col & 4 > 0 THEN 1 ELSE 0 END) "0000100"
, SUM(CASE WHEN bit_col & 2 > 0 THEN 1 ELSE 0 END) "0000010"
, SUM(CASE WHEN bit_col & 1 > 0 THEN 1 ELSE 0 END) "0000001"
FROM my_table
;
1000000 | 0100000 | 0010000 | 0001000 | 0000100 | 0000010 | 0000001
---------+---------+---------+---------+---------+---------+---------
11 | 8 | 11 | 13 | 11 | 9 | 8
To have the results in a single column you need to use union:
SELECT 1 AS "col", SUM(CASE WHEN bit_col & 64 > 0 THEN 1 ELSE 0 END) AS bit_count FROM my_table
UNION ALL SELECT 2 AS "col", SUM(CASE WHEN bit_col & 32 > 0 THEN 1 ELSE 0 END) AS bit_count FROM my_table
UNION ALL SELECT 3 AS "col", SUM(CASE WHEN bit_col & 16 > 0 THEN 1 ELSE 0 END) AS bit_count FROM my_table
UNION ALL SELECT 4 AS "col", SUM(CASE WHEN bit_col & 8 > 0 THEN 1 ELSE 0 END) AS bit_count FROM my_table
UNION ALL SELECT 5 AS "col", SUM(CASE WHEN bit_col & 4 > 0 THEN 1 ELSE 0 END) AS bit_count FROM my_table
UNION ALL SELECT 6 AS "col", SUM(CASE WHEN bit_col & 2 > 0 THEN 1 ELSE 0 END) AS bit_count FROM my_table
UNION ALL SELECT 7 AS "col", SUM(CASE WHEN bit_col & 1 > 0 THEN 1 ELSE 0 END) AS bit_count FROM my_table
ORDER BY bit_count DESC
;
position | bit_count
----------+-----------
6 | 6
7 | 6
4 | 4
5 | 4
2 | 0
3 | 0
1 | 0
http://docs.aws.amazon.com/redshift/latest/dg/r_OPERATOR_SYMBOLS.html
EDIT: If you would like something more dynamic you will need to look into using a UDF. You could start with my f_bitwise_to_string UDF as a template and add what you need from there. https://github.com/awslabs/amazon-redshift-udfs/blob/master/scalar-udfs/f_bitwise_to_string.sql

SQL consolidate data and turn them into columns

So here's what my data table looks like:
TeamNum Round Points1 Points2
1 1 5 21
2 1 10 20
3 1 9 29
1 2 6 22
2 2 11 21
3 2 10 30
1 3 80 50
I also have a second table with this:
TeamNum TeamName
1 goteam1
2 goteam2
3 goteam4-1
I want SQL to take it and turn it into this:
Team Round1 Round2 Round3 TeamName
1 (points1+points2 of round1) (same but for r2) (same but for r3) goteam1
2 (points1+points2 of round1) (same but for r2) (same but for r3) goteam2
3 (points1+points2 of round1) (same but for r2) (same but for r3) goteam4-1
And a sample output from the tables above would be:
Team Round1 Round2 Round3 TeamName
1 26 28 130 goteam1
2 30 32 0 goteam2
3 38 40 0 goteam4-1
The actual data has a bunch of "points1" and "points2" columns, but there are only 3 rounds.
I am very new to SQL and this is all I have right now:
select
`data`.`round`,
`data`.`teamNumber`,
sum(`Points1`) + sum(`Points2`) as score
from `data` join `teams` ON `teams`.`teamNumber` = `data`.`teamNumber`
group by `data`.`teamNumber` , `round`
order by `data`.`teamNumber`, `data`.`round`
But it doesn't return anything at all. If I remove the join statement, it shows everything like I want, but doesn't consolidate Round1, 2, and 3 as columns, they are each separate rows. Can you guys help me out? Thanks!
Use conditional aggregation
SELECT t.teamnumber, t.teamname,
SUM(CASE WHEN d.round = 1 THEN d.points1 + d.points2 ELSE 0 END) round1,
SUM(CASE WHEN d.round = 2 THEN d.points1 + d.points2 ELSE 0 END) round2,
SUM(CASE WHEN d.round = 3 THEN d.points1 + d.points2 ELSE 0 END) round3
FROM data d JOIN teams t
ON d.teamnumber = t.teamnumber
GROUP BY t.teamnumber, t.teamname
Output:
| TEAMNUMBER | TEAMNAME | ROUND1 | ROUND2 | ROUND3 |
|------------|-----------|--------|--------|--------|
| 1 | goteam1 | 26 | 28 | 130 |
| 2 | goteam2 | 30 | 32 | 0 |
| 3 | goteam4-1 | 38 | 40 | 0 |
Here is SQLFiddle demo
No need to aggregate:
SELECT
t.teamnumber,
COALESCE(r1.points1 + r1.points2, 0) AS round1,
COALESCE(r2.points1 + r2.points2, 0) AS round2,
COALESCE(r3.points1 + r3.points2, 0) AS round3,
t.teamname
FROM teams t
LEFT JOIN data r1 ON r1.teamnumber = t.teamnumber AND r1.round = 1
LEFT JOIN data r2 ON r2.teamnumber = t.teamnumber AND r2.round = 2
LEFT JOIN data r3 ON r3.teamnumber = t.teamnumber AND r3.round = 3
Something like this:
select teams.teamNumber,
SUM(CASE WHEN Round=1 THEN `Points1`+`Points2` ELSE 0 END)as Round1,
SUM(CASE WHEN Round=2 THEN `Points1`+`Points2` ELSE 0 END)as Round2,
SUM(CASE WHEN Round=3 THEN `Points1`+`Points2` ELSE 0 END)as Round3,
teams.teamName
from `data` join `teams` ON `teams`.`teamNumber` = `data`.`teamNumber`
group by teamnumber , teamname
order by `data`.`teamNumber`, `data`.`round`

How do I count total of value in one column with different data

I'm a bit confuse how to name my question title.
Let say my MySQL database table like this. table_group
UserID UserGroup UserStatus
------------------------------
1 1 1
2 1 1
3 1 2
4 2 3
5 3 2
6 3 1
7 4 3
9 4 4
10 4 1
I want to group it by UserGroup and count the UserStatus.
Let me know what is the correct statement to get the result like this
UserGroup Status_1 Status_2 Status_3 Status_4
-------------------------------------------------
1 2 2 0 0
2 0 0 1 0
3 1 1 0 0
4 1 0 1 1
SELECT UserGroup, count(UserStatus = 1) as Status_1, count(UserStatus = 2) as Status_2,
count(UserStatus = 3) as Status_3, count(UserStatus = 4) as Status_4
FROM table_group GROUP BY UserGroup
You could use case to count rows that match a condition:
select UserGroup
, count(case when UserStatus = 1 then 1 end) as Status_1
, count(case when UserStatus = 2 then 1 end) as Status_2
, count(case when UserStatus = 3 then 1 end) as Status_3
, count(case when UserStatus = 4 then 1 end) as Status_4
from table_group
group by
UserGroup

Counting Null values in MYSQL

How do i count null values while making cross tab query?
I have a table with three colums [id, name, answer]
i have following records:
ID NAME ANS
1 ABC 1
1 ABC 0
1 ABC NULL
2 XYZ 1
2 XYZ NULL
2 XYZ NULL
2 XYZ 1
2 XYZ 0
1 ABC 0
now i would like to get my result:
ID Name NULLCOUNT TRUE COUNT FALSE COUNT
1 ABC 1 1 2
2 XYZ 2 2 1
I am using following SQL Statement:
select ID, NAME,
sum(case ANS when null then 1 else 0 end) as NULLCOUNT,
sum(case ANS when 1 then 1 else 0 end) as TRUECOUNT,
sum(case ANS when 0 then 1 else 0 end) as FALSECOUNT
from
TBL1
Group By ID, Name
Getting my result:
ID Name NULLCOUNT TRUE COUNT FALSE COUNT
1 ABC 0 1 2
2 XYZ 0 2 1
The NULL Count is getting error. Why and how can i solve this?
I believe instead of this:
sum(case ANS when null then 1 else 0 end) as NULLCOUNT
You should use this:
sum(case when ANS is null then 1 else 0 end) as NULLCOUNT
null -> is null?
NULL doesn't even compare with itself, you could use "CASE WHEN ANS is NULL"(you're also missing GROUP BY). Or try:
select ID, NAME,
sum(if(ans IS NULL, 1, 0)) as NULLCOUNT,
sum(case ANS when 1 then 1 else 0 end) as TRUECOUNT,
sum(case ANS when 0 then 1 else 0 end) as FALSECOUNT
from
TBL1
group by ID,NAME