How can I create multiple groups within a column using SQL - sql

I have a data set that looks like the below
follower_count
5,689
15,389
215,869
53,389
28,389
9,389
I essentially want to create 3 different groups.
Group 1: Follower_count between 0-25,000 called micro
Group 2: Follower_count between 25,001 to 50,0000 called mid
Group 3: Follower_count between 50,001 - 300,000 called macro
This is the code I have so far
SELECT pic.followers_count, AVG(engagement_rate / 1000000) AS avgER
FROM `public_instagram_channels` AS pic
WHERE pic.followers_count BETWEEN 0 and 25000 AS micro,
pic.followers_count BETWEEN 25001 and 50,000 AS mid,
pic.followers_count BETWEEN 50,001 - 300,000 as macro
GROUP BY micro, mid, macro

You would use a case expression:
select (case when follower_count < 25000 then 'micro'
when follower_count < 50000 then 'mid'
when follower_count < 300000 then 'maccro'
else 'other'
end) as grp, count(*),
avg(engagement_rate / 1000000)
from `public_instagram_channels` p
group by grp;

Related

SQL sum with limit

i need to sum working hours from employees with some limitations. My code right now just for one employee:
SELECT rp.mnr,
trunc(sum(rp.OUT_DATE-rp.IN_DATE)*24, 2) AS "Hours"
FROM table1 rp
WHERE rp.CALC_DATE >= '01.04.2022' and rp.CALC_DATE <= '30.4.2022'
AND rp.MNR = 90590
GROUP BY rp.MNR
ORDER BY rp.mnr desc
MNR |Hours |
-----+------+
90590|181.98|
I need to split this sum with hours limit 50.. Result should look like:
MNR |Hours |
-----+------+
90590|50.00|
90590|50.00|
90590|50.00|
90590|31.98|
Anyone can help me with that ?
DB: Oracle.
Thank you!
MF
You have to generate the required rows to get your desired output. CONNECT BY clause is one of the method -
WITH DATA AS (<YOUR SELECT QUERY GIVING COLUMNS AS MNR AND HOURS>),
FIXED_AMOUNT AS (SELECT 50 AMT FROM DUAL),
CALC AS (SELECT D.*, AMT, SUM(AMT) OVER (ORDER BY ROWNUM) CUMM_SUM
FROM DATA D, FIXED_AMOUNT
CONNECT BY (LEVEL - 1) * 50 <= HOURS)
SELECT MNR, CASE WHEN HOURS_ - CUMM_SUM < 0
THEN HOURS_ - CUMM_SUM + AMT
ELSE AMT
END HOURS
FROM CALC;
Demo.

How can I return a count of how many orders fall within incremental ranges?

I have columns called order_id and purchase_amount, and I need to write a query to count how many orders fall within each incremental range of $100, along with the values of the range. For example, it has to return something like 12 orders are between $0-100, 9 orders are between $101-200 and continuing on that way, increasing by $100 each time, like below. And I'm stumped how to begin.
Count | Range
12 | $0-100
9 | $101-200
Look at using SQL function SUM combined with CASE to create a condition.
Select SUM(CASE WHEN OrderValue >= 0 AND OrderValue < 100 THEN 1 ELSE 0 END) AS Count FROM Table;
That should give you a starting point.
You didn't provide any source table data sample so I did use the standard table Orders from TPCH to build the following:
select
case
when o_totalprice < 1000 then '1k-'
when o_totalprice >= 1000 and o_totalprice < 5000 then '1k-5k'
when o_totalprice >= 5000 and o_totalprice < 10000 then '5k-10'
when o_totalprice >= 10000 and o_totalprice < 20000 then '10k-20k'
when o_totalprice >= 20000 and o_totalprice < 50000 then '20k-50k'
else '50k+'
end as 'Range',
count(*) as 'Range-Count'
from
orders
group by 1
;
Hope this answer your question...

SQL Increment column value in select statement

I'm trying to write a Select statement that increments a column value by 50, but the range can end up being 200,000 so I can't do it all in a case statement manually.
Something similar to this, but instead of manually writing the increments
Select count(order_id) as order_count,
case when revenue between 0 and 50 then ‘$50’
when order_value between 51 and 100 then ‘$100’
else ‘over $101’
end as revenue_bucket
from Orders
group by 2
Turn your revenue into the bucket value, then make string out of it:
SELECT count(order_id) AS order_count,
'$' || ((((revenue - 0.01)/50)::int + 1) * 50)::text AS revenue_bucket
FROM Orders
GROUP BY 2;
This obviously runs well past $200,000.
You can work with modulo to get this. Limit would be 101 in your example. All you have to do, is cast the result in a string and add the $ before it
Select count(order_id) as order_count,
case when revenue < limit then revenue - (revenue % 50) + 50
else ‘over $101’
end as revenue_bucket
from Orders
group by 2
You can round to the nearest 50 with div (integer division):
revenue div 50 * 50
To round up instead of down:
(revenue div 50 + 1) * 50
To include 50 in the next bracket (so 50 as $50 instead of $100):
((revenue-1) div 50 + 1) * 50
Example query:
select revenue
, concat('$', ((revenue-1) div 50 + 1) * 50) as revenue_bucket
from YourTable
See it working at SQL Fiddle.
figured out something similar
select floor((revenue+49)/50)*50 as revenue_bucket,
count(1) as order_count
from Orders
group by 1;

Deriving a thousands or hundreds range from a number in T-SQL

We have several thousand job numbers stored in a SQL Server database, and I'd like to be able to derive what 1000's or 100's range they fall into for purposes of grouping in a third party application, which is integrated with our jobs list.
How can I extract the 1000's group that each job number would belong to in a column in my query's result set?
Examples:
I would like for my output to be:
JOB_NUMBER JOB_GROUP
678 0-999
679 0-999
1517 1000-1999
2011 2000-2999
2150 2000-2999
...etc.
If job_number is an integer, you can use this:
select job_number,
convert(varchar(10), job_number / 1000 * 1000)
+ '-'
+ convert(varchar(10), job_number / 1000 * 1000 + 999) Range
from whatever
You could use a CASE expression:
SELECT
JOB_NUMBER,
JOB_GROUP = CASE
WHEN JOB_NUMBER < 1000 THEN '0-999'
WHEN JOB_NUMBER < 2000 THEN '1000-1999'
WHEN JOB_NUMBER < 3000 THEN '2000-2999'
END
try this:
WITH CTE AS(
SELECT JOB_NUMBER/1000 AS JOB_NUMBER,MIN(JOB_NUMBER) AS MIN_NUMBER,
MAX(JOB_NUMBER) AS MAX_NUMBER
FROM <TABLE>
GROUP BY NUMBER/1000)
SELECT M.JOB_NUMBER,
CAST(MIN_NUMBER AS VARCHAR(20))+'-'+CAST(MAX_NUMBER AS VARCHAR(20))
FROM <TABLE> M
JOIN CTE
ON MIN_NUMBER<= M.JOB_NUMBER
AND MAX_NUMBER >=M.JOB_NUMBER
ORDER BY M.JOB_NUMBER

How can I calculate a column data for different conditions using single query in sql server?

I am using below query to count a particular column data based on single condition.
SELECT COUNT(DISTINCT(S.INVOICENO)) AS LESSTWO , YEAR(S.invoicedate) YER,
Month(S.invoicedate) MNTH
FROM SALESDATA S
where S.BILLINGTYPE='INVOICE'
AND (S.invoicedate >='4-1-2009' and S.invoicedate <='4-30-2010')
AND S.TAXABLEAMT <=2000
GROUP BY YEAR(S.invoicedate) ,Month(S.invoicedate)
ORDER BY YEAR(S.invoicedate) ,Month(S.invoicedate)
But I have to calculate for 3 more conditions. Is it possible to count based on 3 conditions(i.e. 2001 - 3000,3001 - 4000, 4001 - 5000,>5000) and I want result set for all the conditions?
Regards,
N.SRIRAM
Untested, but should be about right:
SELECT CASE
WHEN S.TaxableAmt <= 2000 THEN '<=2000'
WHEN S.TaxableAmt <= 3000 THEN '2001-3000'
WHEN S.TaxableAmt <= 4000 THEN '3001-4000'
ELSE '>5000'
END as Bracket,
COUNT(DISTINCT(S.INVOICENO)) AS LESSTWO , YEAR(S.invoicedate) YER,
Month(S.invoicedate) MNTH
FROM SALESDATA S
where S.BILLINGTYPE='INVOICE'
AND (S.invoicedate >='20090401' and S.invoicedate <='20100430')
GROUP BY
CASE
WHEN S.TaxableAmt <= 2000 THEN '<=2000'
WHEN S.TaxableAmt <= 3000 THEN '2001-3000'
WHEN S.TaxableAmt <= 4000 THEN '3001-4000'
ELSE '>5000'
END,
YEAR(S.invoicedate) ,Month(S.invoicedate)
ORDER BY YEAR(S.invoicedate) ,Month(S.invoicedate)
You have to repeat the case expression in the GROUP BY clause (or put it all in a subquery), and I've fixed your date constants so that they're unambiguous.
I think you really need to split up the query into 3 distinct queries - one for each of the conditions you require