Query from same table to extract different data - sql

In a single table I have 3 columns. First defines a sector, second count and third amount. I need to extract 5 columns of data in the following manner. First column sector. Second and third to contains the values were amount is less than count and third and four to display were amount is more than count in the specific sectors. How should my query look?
Sample Data - 4 row data for sector one.
1,23,44
1,20,15
1,50,45
1,30,20
Result should be
1,100,80,23,44

You can get it done using a GROUP BY and SUM() aggregate function along with CASE statement like
SELECT sector,
SUM(case when count > amount then count else 0 end) as count1,
SUM(case when amount < count then amount else 0 end) as amount1,
SUM(case when count < amount then count else 0 end) as count2,
SUM(case when amount > count then amount else 0 end) as amount2
FROM mytable
GROUP BY sector;

Related

SQL query select returns different result than expected

I'm querying on this 2 tables:
TIMBRATURE
ASSELEMGEN
This is my query:
select convert(varchar(11),convert(date,datav),105) as data,
sum (CASE WHEN idterminale=3 and DATEPART(hour,datav)>='9' and DATEPART(hour,datav)<='16' THEN 1 ELSE 0 END) as pranzoP,
sum (CASE WHEN idterminale=3 and DATEPART(hour,datav)>='17' and DATEPART(hour,datav)<='23' THEN 1 ELSE 0 END) as cenaP,
sum (CASE WHEN idterminale=3 THEN 1 ELSE 0 END) as totaleP
from TIMBRATURE where DATAV>=#dataDa and DATAV<#primoGGmeseSuccessivo and TIMBRATURE.IDDIP
in (select iddip from ASSELEMGEN where IDELEM=1001)
group by convert(date,datav)
order by convert(date,datav)
For this purpose consider this argumets:
declare #datada as date='20230201'
declare #primoggmesesuccessivo as date='20230207'
The result I get:
Iddip is user ID, problem is when user have 2 entries for the same day, one with datav hour part between 9 and 16, the other between 17 and 23. In this case I have to count 2 for it, but my query only count it once. For example in the result above on 1th February I expect PranzoP=93 and totaleP=130.

SQL Summing columns based on date key

I have a dataset as given in the link, DataSet
I want to segregate the column "order_item_unit_status" as separate column and bring respective transaction amount for the same. Desired output is given below.
Objective is to consolidate the txn_amt into respective categories and group them based on txn_date_key. (Basically pivoting based on order_item_unit_status column and bringing txn_amt respectively.)
I used the below code,
Select *, CASE WHEN order_item_unit_status ='DELIVERED'
THEN txn_amt ELSE 0 END as DELIVERED,
CASE WHEN order_item_unit_status ='RETURNED'
THEN txn_amt ELSE 0 END as RETURNED
from sales
Got output as referred in the link Output
The output is not grouping based on txn_date_key and multiple line items found. If i use GROUP BY txn_date_key an error is thrown.
Also I was informed that server is supported by HiveSQL and does not support of using ":", date time, and temp tables can not be created. I'm currently stuck on how to go about given the constraints.
Help would be much appreciated
You have to use your columns in the group by:
EDIT: also SUM() added for the correct output...
Select *,
SUM(CASE WHEN order_item_unit_status ='DELIVERED'
THEN txn_amt ELSE 0 END) as DELIVERED,
SUM(CASE WHEN order_item_unit_status ='RETURNED'
THEN txn_amt ELSE 0 END) as RETURNED
from sales
group by txn_amt,txn_date_key,order_item_unit_status
In hivesql you can use from_unixtime command
Unixtime
All columns which are not aggregated and selected shold be in group by.
This query produces result you need:
Select txn_date_key,
sum(CASE WHEN order_item_unit_status ='DELIVERED'
THEN txn_amt ELSE 0 END) as DELIVERED,
sum(CASE WHEN order_item_unit_status ='RETURNED'
THEN txn_amt ELSE 0 END) as RETURNED
from sales
group by txn_date_key
Result:
txn_date_key delivered returned
20190701 3200 0
20210631 0 3000

SQL using SUM in CASE in SUM

I had this query select
sum(CASE WHEN kpi.average >= temp.average THEN 1 ELSE 0 END) AS recordOrder,
which worked fine, but I had to change it to this
sum(CASE WHEN sum(kpi.averageUse) / sum(kpi.averageTotal) >= temp.average THEN 1 ELSE 0 END) AS recordOrder,
These queries have to get number of rows, where some value (average) is greater than average from TEMP table. But in the second query I have more accurate data (weighted average).
but I am getting error
1111 invalid use of group function
Any ideas how to write SUM in CASE in SUM?
Thanks!
This code is just non-sensical because you have nested sum functions:
sum(CASE WHEN sum(kpi.averageUse) / sum(kpi.averageTotal) >= temp.average THEN 1 ELSE 0 END) AS recordOrder,
Without seeing your larger query, it is not possible to know what you really intend. But I would speculate that you don't want the internal sum()s:
sum(CASE WHEN (skpi.averageUse / kpi.averageTotal) >= temp.average THEN 1 ELSE 0 END) AS recordOrder,

SQL select grouping and subtract

i have table named source table with data like this :
And i want to do query that subtract row with status plus and minus to be like this group by product name :
How to do that in SQL query? thanks!
Group by the product and then use a conditional SUM()
select product,
sum(case when status = 'plus' then total else 0 end) -
sum(case when status = 'minus' then total else 0 end) as total,
sum(case when status = 'plus' then amount else 0 end) -
sum(case when status = 'minus' then amount else 0 end) as amount
from your_table
group by product
There is another method using join, which works for the particular data you have provided (which has one "plus" and one "minus" row per product):
select tplus.product, (tplus.total - tminus.total) as total,
(tplus.amount - tminus.amount) as amount
from t tplus join
t tminus
on tplus.product = tminus.product and
tplus.status = 'plus' and
tplus.status = 'minus';
Both this and the aggregation query work well for the data you have provided. In other words, there are multiple ways to solve this problem (each has its strengths).
you can query as below:
select product , sum (case when [status] = 'minus' then -Total else Total end) as Total
, sum (case when [status] = 'minus' then -Amount else Amount end) as SumAmount
from yourproduct
group by product

Grouping totals by date ranges

I have to get totals from a table using different criteria, which I do like this:
SELECT DISTINCT
SUM(CASE WHEN MYCONDITION1 THEN 1 ELSE 0 END) AS TOTAL1,
SUM(CASE WHEN MYCONDITION2 THEN 1 ELSE 0 END) AS TOTAL2
FROM TABLE1, TABLE2
WHERE COMMON_CONDITION1 AND COMMON_CONDITION2
AND BETWEEN DATE1 AND DATE2;
This works fine and I get the intended result.
Now, I have to repeat this for every week for the last 12 months, excluding holidays period. So, I generate a set of date ranges which will be used in the queries. So, I repeat the above sql statement for all the date ranges, which is a lengthy process.
I have to get the totals for every week. For example from 26-Sep-2010 to 02-Oct-2010, 19-Sep-2010 to 25-Sep-2010, 12-Sep-2010 to 18-Sep-2010, etc.. How should I put those ranges in the query for grouping and in the select list, as I don't have them in a table.
How can I do that in a single shot and get all totals for each date range. Please help me with sql.
Thank you.
You could create a table that contains the date ranges. You can join on the new table; you'll have to replace distinct with group by. For example:
SELECT TABLE3.DATE1
, TABLE3.DATE2
, SUM(CASE WHEN MYCONDITION1 THEN 1 ELSE 0 END) AS TOTAL1
, SUM(CASE WHEN MYCONDITION2 THEN 1 ELSE 0 END) AS TOTAL2
FROM TABLE1, TABLE2, TABLE3
WHERE COMMON_CONDITION1
AND COMMON_CONDITION2
AND DATE_COLUMN BETWEEN TABLE3.DATE1 AND TABLE3.DATE2
GROUP BY
TABLE3.DATE1
, TABLE3.DATE2