How to group by diapasons? [duplicate] - mysql

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

Related

how to aggregation without group_by in mysql?

This is table.
idx
statusIdx
date
1
1
2022-05-12 02:24
2
2
2022-05-12 02:24
3
3
2022-06-12 02:24
4
1
2022-07-12 02:24
5
1
2022-07-12 02:24
6
2
2022-07-12 02:24
How can i get like this?
stauts1
status2
status3
2022-05
1
1
0
2022-06
0
0
1
2022-07
2
1
0
sum
3
2
1
I've tried to use row_number() and count() over().
SELECT
FDATE, cnt1, cnt2, cnt3
FROM
(SELECT
DATE_FORMAT(date, "%Y.%m") AS FDATE,
COUNT(case when statusIdx=1 then 1 end) over(PARTITION BY date, statusIdx) AS cnt1,
COUNT(case when statusIdx=2 then 1 end) over(PARTITION BY date, statusIdx) AS cnt2,
COUNT(case when statusIdx=3 then 1 end) over(PARTITION BY date, statusIdx) AS cnt3,
row_number() over (PARTITION by date, statusIdx) AS rnk
FROM transfer
WHERE date betWEEN "20212-05-01" AND "2022-07-31"
ORDER BY FDATE ASC
) t
WHERE rnk = 1
It show vertically counting.
num
FDATE
cnt1
cnt2
cnt3
1
2022-05
1
0
0
1
2022-05
0
1
0
3
2022-06
0
0
1
4
2022-07
2
0
0
5
2022-07
0
1
0
How to aggregation without group_by in mysql?
Used sum() over partition. see dbfidde link if this works.

MySql: Count occurrences of values by date

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

mysql show month as 0 if no amount is donated for a month

I have a mysql table like this:
id course_id amount created_on
1 2 100 2018-01-03
2 1 300 2018-03-03
3 2 200 2018-01-03
4 4 400 2018-04-03
I would like to pass the course id and get total amount for that course donated for a year, based on month wise. If no donation is made for a month need to show it as 0
output as below:
month amount
1 300
2 0
3 200
4 400
5 0
6 0
7 0
8 0
9 0
10 0
11 0
12 0
You need a calendar month table for this, because there is no guarantee that your current table has data for every month.
SELECT
t1.month,
COALESCE(t2.amount, 0) AS amount
FROM
(
SELECT 1 AS month UNION ALL
SELECT 2 UNION ALL
SELECT 3 UNION ALL
SELECT 4 UNION ALL
SELECT 5 UNION ALL
SELECT 6 UNION ALL
SELECT 7 UNION ALL
SELECT 8 UNION ALL
SELECT 9 UNION ALL
SELECT 10 UNION ALL
SELECT 11 UNION ALL
SELECT 12
) t1
LEFT JOIN
(
SELECT MONTH(created_on) AS month, SUM(amount) AS amount
FROM yourTable
GROUP BY MONTH(created_on)
) t2
ON t1.month = t2.month
ORDER BY
t1.month;

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

Transpose a table

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