I'm trying to count the number of occurences based severity level (1-5) on distinct dates. Note I have another table but severity levels are words (High, Medium and Low...not 1 to 5).
Example of DB:
DATE LEVEL COUNT
---- ----- -----
05/11/2018 3 14
05/11/2018 5 11
05/11/2018 5 11
05/12/2018 3 14
05/12/2018 2 14
05/13/2018 2 11
05/13/2018 1 12
Expected output
Date 1 2 3 4 5
--------- -- -- -- -- --
05/11/2018 0 0 14 0 22
05/12/2018 0 14 14 0 0
05/13/2018 12 11 0 0 0
Expected output 2
Level 05/11/2018 05/12/2018 05/13/2018
--------- ---------- ---------- ----------
1 0 0 12
2 0 14 11
3 14 14 0
4 0 0 0
5 22 0 0
I tried
SELECT CONCAT(DAY(`DATE`) ,MONTH(`DATE`) , YEAR(`DATE`)) AS DDMMYYYY ,
COUNT(DISTINCT LEVEL) as NumCount
FROM `myDatabase`
GROUP BY CONCAT(DAY(`DATE`),MONTH(`DATE`), YEAR(`DATE`) )
but I'm getting the number of different counts..
Any guidance would be appreciated! Thx!
You can't really do pivot tables in MySQL. However with a fixed number of columns (such as expected output #1) you can simulate them with CASE statements e.g.
select date_format(date, '%d%m%Y') as Date,
sum(case when level=1 then count else 0 end) as `1`,
sum(case when level=2 then count else 0 end) as `2`,
sum(case when level=3 then count else 0 end) as `3`,
sum(case when level=4 then count else 0 end) as `4`,
sum(case when level=5 then count else 0 end) as `5`
from table1
group by Date
Output:
Date 1 2 3 4 5
11052018 0 0 14 0 22
12052018 0 14 14 0 0
13052018 12 11 0 0 0
Related
This question already has answers here:
In SQL, how can you "group by" in ranges?
(17 answers)
Closed 4 years ago.
I have got a table 'payments'
user_id amount
1 300
1 100
2 100
2 100
3 10
4 200
What query should I make to display result by groups:
diapason number
0 -10 0
10 - 100 1
100 -200 3
more than 200 2
I think I should use 'having'?
For this type of query you could use a UNION:
SELECT '0-10' as diapason, SUM(CASE WHEN amount < 10 THEN 1 ELSE 0 END) AS number FROM payments
UNION
SELECT '10-100', SUM(CASE WHEN amount BETWEEN 10 AND 99 THEN 1 ELSE 0 END) FROM payments
UNION
SELECT '100-200', SUM(CASE WHEN amount BETWEEN 100 AND 199 THEN 1 ELSE 0 END) FROM payments
UNION
SELECT 'more than 200', SUM(CASE WHEN amount >= 200 THEN 1 ELSE 0 END) FROM payments
Output:
diapason number
0-10 0
10-100 1
100-200 3
more than 200 2
SQLFiddle Demo
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
I am using Mysql and I want count distinct value and then make the distinct values as the column name.
I have a table Students like this
ID Names Age
1 Tim 12
2 James 14
3 White 13
4 John 13
5 Annie 11
6 Judy 13
I want to find how many people in each age. My expected result is:
11 12 13 14
1 1 3 1
I tried the query: "Select count(age), age from Students group by age;"
It gives out:
count(age) age
1 11
1 12
3 13
1 14
How can I take a "transpose" to the table?
If you are using MySQL you will need to know age in advance:
SELECT
SUM(CASE WHEN (age='11') THEN 1 ELSE 0 END) AS 11,
SUM(CASE WHEN (age='12') THEN 1 ELSE 0 END) AS 12,
SUM(CASE WHEN (age='13') THEN 1 ELSE 0 END) AS 13,
SUM(CASE WHEN (age='14') THEN 1 ELSE 0 END) AS 14
FROM
Students
First table :
UserId UserName
1 User1
2 User2
3 User3
4 User4
Second Table
Userid Mark Aptitude English Technical Status
1 40 1 0 0 S
1 30 0 1 0 F
2 60 0 0 1 S
2 75 0 1 0 F
2 25 0 1 0 F
3 45 1 0 0 F
3 45 1 0 0 D
3 50 0 0 1 F
3 50 0 0 1 F
I have this two table. I need a query to get the each user average mark in English, Aptitude and Technical. The average should be calculated only for status F. The result should be like this
UserId AptitudeAverage EnglishAverage TechnicalAverage
1 0 30 0
2 0 50 0
3 45 0 50
4 0 0 0
Try this:-
SELECT userID, IFNULL(AVG(case when Aptitude = 1 then Mark * Aptitude end), 0) AS AptitudeAverage,
IFNULL(AVG(case when English = 1 then Mark * English end), 0) AS EnglishAverage,
IFNULL(AVG(case when Technical = 1 then Mark * Technical end), 0) AS TechnicalAverage
FROM YOUR_TAB
WHERE Status = 'F'
GROUP BY userID;
This might help you.
Here is the fiddle.
http://sqlfiddle.com/#!9/e449f/21
This is my target table
retail_id month tgt_volume product_type
1 2013-11-01 2 Bar
2 2013-10-01 1 Touch
3 2013-09-01 1 Bar
4 2013-10-01 5 Smart
5 2013-10-01 8 Bar
3 2013-08-01 2 Smart
2 2013-08-01 5 Bar
3 2013-07-01 7 Bar
3 2013-07-01 2 Smart
I need this format
retail_id bar smart touch total month
1 2 0 0 2 2013-11-01
2 0 0 1 1 2013-10-01
2 5 0 0 5 2013-08-01
3 1 0 0 1 2013-09-01
3 0 2 0 2 2013-08-01
3 7 2 0 9 2013-07-01
4 0 5 0 5 2013-08-01
5 8 0 0 8 2013-10-01
So I want to retrieve every months total target and each product type total for each retail_id. I was trying a query which count every product_type but not count each month. How can I do this to make above format.. my test query is(without month count)
SELECT DISTINCT t.retail_id,bar_vol.bar,smart_vol.smart,touch_vol.touch,total.total,t.month FROM targets t
LEFT JOIN
(SELECT SUM(tgt_volume) AS bar,retail_id FROM targets t1 WHERE t1.product_type='Bar' GROUP BY retail_id) AS bar_vol
ON t.retail_id=bar_vol.retail_id
LEFT JOIN
(SELECT SUM(tgt_volume) AS smart,retail_id FROM targets t2 WHERE t2.product_type='Smart' GROUP BY retail_id) AS smart_vol
ON t.retail_id=smart_vol.retail_id
LEFT JOIN
(SELECT SUM(tgt_volume) AS touch,retail_id FROM targets t3 WHERE t3.product_type='Touch' GROUP BY retail_id) AS touch_vol
ON t.retail_id=touch_vol.retail_id
LEFT JOIN
(SELECT SUM(tgt_volume) AS total,retail_id FROM targets t4 GROUP BY retail_id) AS total
ON t.retail_id=total.retail_id
You can use a CASE statement inside an aggregate function to achieve this:
SELECT Retail_ID,
SUM(CASE WHEN product_Type = 'Bar' THEN tgt_Volume ELSE 0 END) AS Bar,
SUM(CASE WHEN product_Type = 'smart' THEN tgt_Volume ELSE 0 END) AS Smart,
SUM(CASE WHEN product_Type = 'Touch' THEN tgt_Volume ELSE 0 END) AS Touch,
SUM(tgt_Volume) AS Total,
Month
FROM targets
GROUP BY RetailId, Month;
Example on SQL Fiddle