Oracle/SQL -Sales broken out by Months - sql

Hello I have created the following query to pull total order by month for a salesMen. while this gets me the data I need for a single salesmen i need to run this for more than just one. what I would like to accomplish is a query that pull for several different salesmen and is broken out by month and the Months being the Columns names(Columns dynamic to months being pulled). Like below.
SalesMen - 10-2017 - 11-2017 - 12-2017 - 01/2018
------------------------------------------------------------
Salesmen_1 Month_total(5) 15 300 100
Salesmen_2 100 948 821 684
Current Code:
select (case when region_code in ('123','124') then 'SalesMen_1' else 'N/A' end)SalesMen, to_char(DATE_ENTERED, 'MM-YYYY') as MM_YYYY, Count(ORder_NO) as Month_Total
from ORDERS
where
REGEXP_like (ORder_NO, '^W|^E')
and DATE_ENTERED between ADD_MONTHS(TO_DATE(TO_CHAR(ADD_MONTHS(SYSDATE, 2), 'YYYY') || '-01-01', 'YYYY-MM-DD'), -3) and TO_DATE(TO_CHAR(SYSDATE, 'YYYY-MM')|| '-01', 'YYYY-MM-DD') - 1
and region_code in ('123','124')
group by to_char(DATE_ENTERED, 'MM-YYYY'),(case when region_code in ('123','124') then 'SalesMen_1' else 'N/A' end)
order by to_char(DATE_ENTERED, 'MM-YYYY') desc
Results:
Current Results Example

Related

SQL - SUMIF substitute?

This question is best asked using an example - if I have daily data (in this case, daily Domestic Box Office for the movie Elvis), how can I sum only the weekend values?
If the data looks like this:
Date
DBO
6/24/2022
12755467
6/25/2022
9929779
6/26/2022
8526333
6/27/2022
4253038
6/28/2022
5267391
6/29/2022
4010762
6/30/2022
3577241
7/1/2022
5320812
7/2/2022
6841224
7/3/2022
6290576
7/4/2022
4248679
7/5/2022
3639110
7/6/2022
3002182
7/7/2022
2460108
7/8/2022
3326066
7/9/2022
4324040
7/10/2022
3530965
I'd like to be able to get results that look like this:
Weekend
DBO Sum
1
31211579
2
18452612
3
11181071
Also - not sure how tricky this would be but would love to include percent change v. last weekend.
Weekend
DBO Sum
% Change
1
31211579
2
18452612
-41%
3
11181071
-39%
I tried this with CASE WHEN but I got the results in different columns, which was not what I was looking for.
SELECT
,SUM(CASE
WHEN DATE BETWEEN '2022-06-24' AND '2022-06-26' THEN index
ELSE 0
END) AS Weekend1
,SUM(CASE
WHEN DATE BETWEEN '2022-07-01' AND '2022-07-03' THEN index
ELSE 0
END) AS Weekend2
,SUM(CASE
WHEN DATE BETWEEN '2022-07-08' AND '2022-07-10' THEN index
ELSE 0
END) AS Weekend3
FROM Elvis
I would start by filtering the data on week-end days only. Then we can group by week to get the index sum ; the last step is to use window functions to compare each week-end with the previous one:
select iso_week,
row_number() over(order by iso_week) weekend_number,
sum(index) as dbo_sum,
( sum(index) - lag(sum(index) over(order by iso_week) )
/ nullif(lag(sum(index)) over(order by iso_week), 0) as ratio_change
from (
select e.*, extract(isoweek from date) iso_week
from elvis e
where extract(dayofweek from date) in (1, 7)
) e
group by iso_week
order by iso_week
Consider below
select *,
round(100 * safe_divide(dbo_sum - lag(dbo_sum) over(order by week), lag(dbo_sum) over(order by week)), 2) change_percent
from (
select extract(week from date + 2) week, sum(dbo) dbo_sum
from your_table
where extract(dayofweek from date + 2) in (1, 2, 3)
group by week
)
if applied to sample data in your question - output is

SQL query to use group by to get the sum of two different columns within a date range

I have two tables time track and absence for an employee.
person_number Measure start_Date end_date Time_type
73636 10 01-Jan-2020 02-Jan-2020 Double
73636 24 06-Jan-2020 08-jan-2020 Double
73636 10 15-Jan-2020 25-Jan-2020 Regular Pay
73636 11.9 06-Jan-2020 08-jan-2020 Double
73636 27 10-Jan-2020 15-Jan-2020 Regular Pay
Absence det
person_number start_Date end_date duration Absence_type
73636 05-Jan-2020 10-Jan-2020 10 Vacation
73636 06-Jan-2020 18-jan-2020 9 Paid Leave
73636 20-Jan-2020 21-jan-2020 1 Paid Leave
Now when i pass the from and to date as 01-Jan-2020 and 31-Jan-2020, the output should look like -
Person_Number Double Regular Hour_code hour_amount
73636 31.9 37 Paid Leave 10
The hour_code should have only "Paid Leave" and no other absences
Now I have written the below query for this
SELECT
distinct person_number,
sum(
CASE
WHEN elements = 'Double' THEN measure
END
) AS OT_Hours,
sum(
CASE
WHEN elements LIKE 'Regular Pay%' THEN measure
END
) AS regular_measure_hours,
sum(
CASE
WHEN absence_name IN ('Paid Leave') THEN absence_duration
END
) AS hour3_amount,
max(
CASE
WHEN absence_name IN ('Paid Leave') THEN 'Paid Leave'
END
) AS hour3_code
FROM
(
select
person_number,
Time_type elements,
Absence_type absence_name,
duration,
measure
from
time_track_tab,
abs_tab,
per_all_people_F papf
where
time_track_tab.person_id = abs_tab.person_id
and abs_tab.person_id = papf.person_id
and abs_tab.Absence_type = 'Paid Leave'
)
group by
person_number
This is giving me multiple row output and calculation of sum is not coming correctly as in between the to and from date there are different dates present for both absence and time track.
My requirement is to calculate the sum of ALL the duration and measure column within these parameter dates. How can i tweak my query to get the correct sum between these dates ?
Is there a way to use partition by or group by or anything else to calculation these correctly in the column
You probably need to group both tables first then join them together to avoid the cross join.
select person_number, TimeTrack.DoublePay, TimeTrack.Regular,
Absenses.Hour_code, Absenses.hour_amount from
per_all_people_F papf,
(select
person_id, sum(duration) as hour_amount, Absence_type as Hour_code
from
abs_tab
where
abs_tab.Absence_type = 'Paid Leave'
and
start_Date between '2020-01-01' and '2020-01-31'
group by person_id,Absence_type
) Absenses,
(select
person_id,
sum(case when Time_type = 'Double' then Measure end) as DoublePay,
sum(case when Time_type = 'Regular Pay' then Measure end) as Regular
from time_track_tab
where
start_Date between '2020-01-01' and '2020-01-31'
group by person_id
) TimeTrack
where
papf.person_id = TimeTrack.person_id
and
papf.person_id = Absenses.person_id
and
papf.person_id = 73636
I made a SqlFiddle if you want to play with it
http://sqlfiddle.com/#!9/03e460/36
Also my 2 cents; I'd recommend left outer joining from the per_all_people_F table or else people without absenses will get filtered out.
See if, what you need is something like this:
select * from
(SELECT person_number,
sum(
CASE
WHEN Time_type = 'Double' THEN measure
END
) AS Double,
sum(
CASE
WHEN Time_type = ('Regular Pay') THEN measure
END
) AS regular
from time_track_tab
group by person_number
) A
inner join
(SELECT
person_number,
sum(
CASE
WHEN Absence_type = 'Vacation' THEN duration
END
) AS Vacation,
sum(
CASE
WHEN Absence_type = ('Paid Leave') THEN duration
END
) AS paidLeave
from abs_tab
group by person_number
)B on A.person_number = B.person_number
here the fiddle:
http://sqlfiddle.com/#!4/21253/2

Filtered last transaction

first: I have two tables with a primary key((Agent_ID). I want to join both tables, filter Agent_Type =1 and status =1
Second: get the last active year total transaction value monthly wise who is not done any transaction for the last three months.
Agent table
Agent_ID Agent_Type
234 1
456 1
567 1
678 0
Agent_Transaction table
Agent_ID Amount Transaction_Date status
234 70 23/7/2019 1
234 54 11/6/2019 0
234 30 23/5/2019 1
456 56 12/1/2019 1
456 80 15/3/2019 1
456 99 20/2/2019 1
456 76 23/12/2018 1
567 56 10/10/2018 0
567 60 30/6/2018 1
456
select Agent_ID,CONCAT(Extract(MONTH from Agent_Transaction.Transaction_Date),
EXTRACT (YEAR FROM Agent_Transaction.Transaction_Date))as MONTH_YEAR,
SUM(Agent_Transaction.Amount)AS TOTAL
from Agent
inner join Agent_Transaction
on Agent_Transaction.Agent_ID = Agent.Agent_ID
where Agent.Agent_Type='1' AND Agent_Transaction.status='1' AND
(Agent_Transaction.Transaction_Date between ADD_MONTHS(SYSDATE,-3) and SYSDATE)
GROUP BY Agent.Agent_ID,
CONCAT(Extract(MONTH from Agent_Transaction.Transaction_Date),EXTRACT (YEAR FROM Agent_Transaction.Transaction_Date)),
Agent_Transaction.Amount
But I didn't get what I expected.
As far as I understood the requirement, you can use the following query:
SELECT
A.AGENT_ID,
TO_CHAR(TRUNC(ATR.TRANSACTION_DATE, 'MONTH'), 'MONYYYY'), -- YOU CAN USE DIFFERENT FORMAT ACCORDING TO REQUIREMENT
SUM(AMOUNT) AS TOTAL_MONTHWISE_AMOUNT -- MONTHWISE TRANSACTION TOTAL
FROM
AGENT A
JOIN AGENT_TRANSACTION ATR ON ( A.AGENT_ID = ATR.AGENT_ID )
WHERE
-- EXCLUDING THE AGENTS WHICH HAVE DONE NO TRANSACTION IN LAST THREE MONTHS USING FOLLOWING NOT IN
ATR.AGENT_ID NOT IN (
SELECT
DISTINCT ATR_IN1.AGENT_ID
FROM
AGENT_TRANSACTION ATR_IN1
WHERE
ATR_IN1.TRANSACTION_DATE > ADD_MONTHS(SYSDATE, - 3)
AND ATR_IN1.STATUS = 1 -- YOU CAN USE IT ACCORDING TO REQUIREMENT
)
-- FETCHING LAST YEAR DATA
AND EXTRACT(YEAR FROM ATR.TRANSACTION_DATE) = EXTRACT(YEAR FROM ADD_MONTHS(SYSDATE, - 12))
AND A.AGENT_TYPE = 1
AND ATR.STATUS = 1
GROUP BY
A.AGENT_ID,
TRUNC(ATR.TRANSACTION_DATE, 'MONTH');
Please comment if minor changes are required or you need different logic.
Cheers!!
-- Update --
Updated the query after OP described the original issue:
SELECT
AGENT_ID,
TO_CHAR(TRUNC(TRANSACTION_DATE, 'MONTH'), 'MONYYYY'), -- YOU CAN USE DIFFERENT FORMAT ACCORDING TO REQUIREMENT
SUM(AMOUNT) AS TOTAL_MONTHWISE_AMOUNT -- MONTHWISE TRANSACTION TOTAL
FROM
(
SELECT
A.AGENT_ID,
TRUNC(ATR.TRANSACTION_DATE, 'MONTH') AS TRANSACTION_DATE,
MAX(TRUNC(ATR.TRANSACTION_DATE, 'MONTH')) OVER(
PARTITION BY A.AGENT_ID
) AS LAST_TR_DATE,
AMOUNT,
AGENT_TYPE,
STATUS
FROM
AGENT A
JOIN AGENT_TRANSACTION ATR ON ( A.AGENT_ID = ATR.AGENT_ID )
WHERE
A.AGENT_TYPE = 1
AND ATR.STATUS = 1
)
WHERE
-- EXCLUDING THE AGENTS WHICH HAVE DONE NO TRANSACTION IN LAST THREE MONTHS USING FOLLOWING NOT IN
LAST_TR_DATE > ADD_MONTHS(SYSDATE, - 3)
-- FETCHING LAST YEAR DATA
AND TRANSACTION_DATE BETWEEN ADD_MONTHS(LAST_TR_DATE, - 12) AND LAST_TR_DATE
GROUP BY
AGENT_ID,
TRANSACTION_DATE;
Cheers!!
-- Update --
Your exact query should look like this:
SELECT
AGENT_ID,
TO_CHAR(TRUNC(TX_TIME, 'MONTH'), 'MONYYYY') AS MONTHYEAR,
SUM(TX_VALUE) AS TOTALMONTHWISE
FROM
(
SELECT
A.AGENT_ID,
TRUNC(ATR.TX_TIME, 'MONTH') AS TX_TIME, -- changed this alias name
MAX(TRUNC(ATR.TX_TIME, 'MONTH')) OVER(
PARTITION BY A.AGENT_ID
) AS LAST_TR_DATE,
ATR.TX_VALUE,
A.AGENT_TYPE_ID
FROM
TBLEZ_AGENT A
JOIN TBLEZ_TRANSACTION ATR ON ( A.AGENT_ID = ATR.SRC_AGENT_ID )
WHERE
A.AGENT_TYPE_ID = '3'
AND ATR.STATUS = '0'
AND ATR.TX_TYPE_ID = '5'
)
WHERE
LAST_TR_DATE < ADD_MONTHS(SYSDATE, - 3)
AND ( TX_TIME BETWEEN ADD_MONTHS(LAST_TR_DATE, - 12) AND LAST_TR_DATE )
GROUP BY
AGENT_ID,
TX_TIME;
-- UPDATE --
In response to this comment -- **Hi Tejash, How to get the total day-wise to above my scenario? **
SELECT
AGENT_ID,
TX_TIME,
SUM(TX_VALUE) AS TOTALDAYWISE
FROM
(
SELECT
A.AGENT_ID,
TRUNC(ATR.TX_TIME) AS TX_TIME, -- changed TRUNC INPUT PARAMETER -- REMOVED MONTH IN TRUNC
MAX(TRUNC(ATR.TX_TIME)) OVER( -- changed TRUNC INPUT PARAMETER -- REMOVED MONTH IN TRUNC
PARTITION BY A.AGENT_ID
) AS LAST_TR_DATE,
ATR.TX_VALUE,
A.AGENT_TYPE_ID
FROM
TBLEZ_AGENT A
JOIN TBLEZ_TRANSACTION ATR ON ( A.AGENT_ID = ATR.SRC_AGENT_ID )
WHERE
A.AGENT_TYPE_ID = '3'
AND ATR.STATUS = '0'
AND ATR.TX_TYPE_ID = '5'
)
WHERE
LAST_TR_DATE < ADD_MONTHS(SYSDATE, - 3)
AND ( TRUNC(TX_TIME, 'MONTH') BETWEEN ADD_MONTHS(LAST_TR_DATE, - 12) AND LAST_TR_DATE )
-- changed TRUNC INPUT PARAMETER -- ADDED MONTH IN TRUNC
GROUP BY
AGENT_ID,
TX_TIME;
Cheers!!
SELECT
A.AGENT_ID,
TO_CHAR(TRUNC(ATR.TX_TIME, 'MONTH'), 'MONYYYY') AS MONTHYEAR,
SUM(ATR.TX_VALUE) AS TOTALMONTHWISE
FROM
(
SELECT
A.AGENT_ID,
TRUNC(ATR.TX_TIME, 'MONTH') AS TRANSC_DATE,
MAX(TRUNC(ATR.TX_TIME, 'MONTH')) OVER(
PARTITION BY A.AGENT_ID
) AS LAST_TR_DATE,
ATR.TX_VALUE,
A.AGENT_TYPE_ID
FROM
TBLEZ_AGENT A
JOIN TBLEZ_TRANSACTION ATR ON ( A.AGENT_ID = ATR.SRC_AGENT_ID )
WHERE
A.AGENT_TYPE_ID = '3'
AND ATR.STATUS = '0'
AND ATR.TX_TYPE_ID = '5'
)
WHERE
LAST_TR_DATE > ADD_MONTHS(SYSDATE, - 3)
AND ( TX_TIME BETWEEN ADD_MONTHS(LAST_TR_DATE, - 12) AND LAST_TR_DATE )
GROUP BY
A.AGENT_ID,TRUNC(ATR.TX_TIME, 'MONTH')

How to add static values to SQL QUERY Result set in ORACLE

I have a SQL Query that works perfectly. I am using Oracle 11g. The current SQL Query lists upcoming flights for the next 6 months and then list all past flights afterwards. So my query lists all flights for 2018 first and then all old flights after dating back early as 1998. I need to add two static values to this query. The two static values I want to add are "UPCOMING FLIGHTS" and "PAST FLIGHTS" to distinguish which flights are new and old. How can I achieve this? I need to incorporate this added code with the current SQL query that I have below. I have not been able to do this.
Current SQL Query:
SELECT FLIGHT_NMBR, SCHEDULED_LAUNCH_DATE
FROM FLIGHTS
WHERE DATA_VERSION_NAME = 'WORKING'
AND sequence_nmbr >= 0
ORDER BY (CASE WHEN to_date(scheduled_launch_date, 'DD-MON-YY')
BETWEEN add_months(trunc(sysdate, 'MON'), 0)
AND add_months(trunc(sysdate, 'MON'), 6) THEN 1 ELSE 2 END),
(CASE WHEN to_date(scheduled_launch_date, 'DD-MON-YY')
BETWEEN add_months(trunc(sysdate, 'MON'), 0)
AND add_months(trunc(sysdate, 'MON'), 6) THEN SCHEDULED_LAUNCH_DATE END),
sequence_nmbr;
Results of current SQL query above:
FLIGHT_NMBR SCHEDULED
------------ ---------
SpX-14 26-JAN-18
69P 09-FEB-18
SpX-DM1 09-MAR-18
54S 13-MAR-18
OA-9 14-MAR-18
55S 29-APR-18
SpX-15 06-JUN-18
SpX-DM2 22-JUN-18
70P 27-JUN-18
1A/R 20-NOV-98
2A 04-DEC-98
How can I achieve the desired result set below:
FLIGHT_NMBR SCHEDULED
------------ ---------
UPCOMING FLIHGTS-------------------------------STATIC VALUE I WANT TO ADD
SpX-14 26-JAN-18
69P 09-FEB-18
SpX-DM1 09-MAR-18
54S 13-MAR-18
OA-9 14-MAR-18
55S 29-APR-18
SpX-15 06-JUN-18
SpX-DM2 22-JUN-18
70P 27-JUN-18
PAST FLIGHTS-----------------------------------STATIC VALUE I WANT TO ADD
1A/R 20-NOV-98
2A 04-DEC-98
Want my dropdown to look like this:
you can do it this way,
SELECT 'UPCOMING FLIHGTS' text, NULL sched
FROM dual
UNION ALL
<your select query for upcoming flights>
UNION ALL
SELECT 'PAST FLIGHTS' text, NULL sched
FROM dual
UNION ALL
<your select query for past flights>
What you want to do should be done at the application level. A SQL query returns a result set, which is a table -- consisting of rows with identical columns. Your new rows are not in the same format.
You can simplify the logic and include the flag on each row;
SELECT which, FLIGHT_NMBR, SCHEDULED_LAUNCH_DATE
FROM (SELECT F.*,
(CASE WHEN to_date(scheduled_launch_date, 'DD-MON-YY') BETWEEN add_months(trunc(sysdate, 'MON'), 0) AND add_months(trunc(sysdate, 'MON'), 6)
THEN 'UPCOMING' ELSE 'PAST'
END) as which
FROM FLIGHTS F
) F
WHERE DATA_VERSION_NAME = 'WORKING' AND sequence_nmbr >= 0
ORDER BY (CASE WHEN which = 'UPCOMING' THEN 1 ELSE 2 END),
(CASE WHEN which = 'UPCOMING' THEN SCHEDULED_LAUNCH_DATE END),
sequence_nmbr;

java financial year wise sum Of Amount

I am stuck with a query to fetch sum of transaction amount financial year wise.
My table is
TXN_DATE TXN_AMOUNT
12/01/2014 100
12/08/2014 200
12/01/2015 300
12/04/2015 400
12/04/2013 500
I want the result to be displayed as
FinYear Amount
2013-2014 600
2014-2015 500
2015-2016 400
Considering financial year duration from 1st April of an year to 31st March of next year.
Databse DB2
Date is timestamp in database and date format specified in the example is dd/MM/yyyy
Following query should do (tested in DB2 LUW):
with temp as (finyear, txn_amount) as (
select case
when month(TXN_DATE)< 4 Then year(TXN_DATE)-1 || '-' || year(TXN_DATE)
else month(TXN_DATE)>= 4 Then year(TXN_DATE) || '-' || year(TXN_DATE)+1
end as finyear,
txn_amount
from test4)
select finyear,
sum(txn_amount) as sum_amount
from temp
group by finyear;
SELECT FinYear, cast(sum(Amount) as decimal(16,2)) AS Amount FROM
(SELECT
CASE
WHEN TXN_DATE > to_date(year(TXN_DATE) ||'-03-31','YYYY/MM/DD') THEN CONCAT(CONCAT(year(TXN_DATE),'-'),year(TXN_DATE)+1)
WHEN TXN_DATE < to_date(year(TXN_DATE) ||'-04-01','YYYY/MM/DD') THEN CONCAT(CONCAT(year(TXN_DATE)-1,'-'),year(TXN_DATE))
END as FinYear,
Amount AS Amount
FROM tab1)
GROUP BY FinYear
You can use following query:
SELECT FinYear, sum(Amount) AS Amount FROM
(SELECT FinYear =
CASE
WHEN TXN_DATE > char(year(TXN_DATE)) +'0331' THEN char(year(TXN_DATE))+'-'+char(year(TXN_DATE)+1)
WHEN TXN_DATE < char(year(TXN_DATE)) +'0401' THEN char(year(TXN_DATE)-1)+'-'+char(year(TXN_DATE))
END,
TXN_AMOUNT AS Amount
FROM DB2.Transactions) AS Table1
GROUP BY FinYear
Make sure you replace DB2.Transactions with your DatabaseName.TableName