SQL Getting Date Range - sql

I need to aggregate costs to be displayed by date range per month. To illustrate please take a look at the following:
Sample Data
invoice_id usage_date cost
--------------------------------------
123 May 31, 2016 $4
150 June 01, 2016 $4
150 June 02, 2016 $4
150 June 03, 2016 $4
150 June 04, 2016 $5
150 June 05, 2016 $5
...
150 June 30, 2016 $5
240 July 01, 2016 $8
Taking into account the data above, I want to get
Desired Result
range total
-----------------------------
June 01-03, 2016 $12
June 04-30, 2016 $135
As you'll notice I want to group them and add those with the same cost but display the dates as start to end. But this has to be done for each month only. In this particular case, let's say May 31, 2016 incurred a cost of $4, it wouldn't be included even though it has the same cost with the next day (June 01) because they're from different months.
I feel like I need to provide more information but I'm not sure what you guys still need so just comment what you want me to add.
EDIT
I don't know if this matters but let me just add a query I used to generate the sample data I provided above.
Sample Data - SQL
SELECT id.invoice_id, di.usage_date, SUM(di.item_cost) AS cost
FROM detail_items di
LEFT JOIN invoice_details id
ON id.id = di.detail_id
WHERE di.group_id = 123456
GROUP BY id.invoice_id, di.usage_date

Aggregate by year, month and cost and get the min and max dates for a given cost. Then multiply the cost with the total rows in a given month to get the total.
select to_char(mindt,'mm/dd/yyyy')||'-'||to_char(maxdt,'mm/dd/yyyy') daterange,
cnt*cost total
from (
select
cost, min(usage_date) mindt, max(usage_date) maxdt, count(*) cnt,
to_char(usage_date,'mm') usg_mth,to_char(usage_date,'yyyy') usg_yr
from tablename
group by to_char(usage_date,'mm'),to_char(usage_date,'yyyy'),cost
) t

Related

Sum of totals grouped by month

I've been out of the dev world for a few years so forgive me if this is a pretty basic question but I have an app that logs bookings for holiday accomodation. I want to produce a report detailing how much income per month a user gets.
My query thus far is as so:-
SELECT SUM(int_ToOwner) AS TotalIncome,
DateName(m,dtm_StartDate) AS BookingMonth
FROM tbl_Bookings
WHERE dtm_StartDate > '2021-12-31'
GROUP BY DatePart(m,dtm_StartDate), int_ToOwner, dtm_StartDate
But that produces the result below. I want it to give me a total for each month instead.
TotalIncome
BookingMonth
553.00
January
849.00
January
885.00
February
1236.00
February
1239.00
February
896.00
March
927.00
March
940.00
March
959.00
March
971.00
March
1167.00
April
1255.00
April
1500.00
April
2461.00
April
1131.00
May
1172.00
May
1275.00
May
2647.00
May
1466.00
June
1480.00
June
1496.00
June
1899.00
June
2167.00
June
1881.00
July
4990.00
July
4991.00
July
2134.00
August
4162.00
August
4883.00
August
5329.00
August
1430.00
September
1630.00
October
1130.00
November
You almost have it but you are also grouping by int_ToOwner and you have the dtm_StartDate twice.
Try:
SELECT SUM(int_ToOwner) AS TotalIncome, DateName(m,dtm_StartDate) AS BookingMonth
FROM tbl_Bookings
WHERE dtm_StartDate > '2021-12-31'
GROUP BY DatePart(m,dtm_StartDate)
A little re-format:
SELECT SUM(int_ToOwner) AS TotalIncome
, DateName(m,dtm_StartDate) AS BookingMonth
FROM tbl_Bookings
WHERE dtm_StartDate > '2021-12-31'
GROUP BY DatePart(m,dtm_StartDate)
, int_ToOwner
, dtm_StartDate
Your GROUP BY tells the database to create groups for data with equal values of
DatePart(m,dtm_StartDate)
int_ToOwner
dtm_StartDate
Then SELECT asks for each group the
calculated SUM of int_ToOwner
DateName(m,dtm_StartDate)
You should search your solution in grouping the correct attributes.

getting sum for each month for several months in a year in sql

I have the following table
image of database in use
i want to get the following kind of results
jan 12500
feb 16500
mar 4500
apr 6500
the query should return a total for each month for desired months.
i know how to do this..
$sql = "SELECT SUM(cost) as january FROM earnings WHERE month= 1 and year= '$2022" ;
to get the sum for a given month but I cant find anything on how to get multiple months at once.
am still new to this
SELECT
SUM(cost) as cost,
month
FROM earnings
WHERE year = :year
GROUP BY month
Sum all entries of cost, per month (GROUP BY) found in year (:year)
Each ROW will have a column cost and month.
If you want to "further" filter the months you can apply another AND clause
AND (month >= 1 OR month <= 6) for January to June
Useful Source:
https://www.mysqltutorial.org/mysql-group-by.aspx

How to display multiple rows or one row, depending on the condition, in SQL Developer

I am revising a SQL Developer query that pulls transaction data for salespeople from the selected period; the selected period is always a month, e.g. where periodname = 'March 2017'.
However, some of the salespeople are paid monthly, while others are paid quarterly. With the current query, if a quarterly salesperson has a transaction in January, but does not have a transaction in February or March, they would only show up on the January 2017 pull.
I would like to return all transactions QTD for quarterly salespeople, and continue returning transactions MTD for monthly salespeople; i.e. if I run the query for March 2017, a quarterly salesperson would see any transactions from January 2017, February 2017, and March 2017, while a monthly salesperson would only see transaction for March 2017. If I run the query for June 2017, a quarterly salesperson should see any transactions from April 2017 and June 2017, and a monthly salesperson would see transactions from June 2017.
My table has these key elements:
PERIODSEQ PARENTSEQ SALESPERSONNAME TRANSACTIONTYPE PAYFREQ
109 106 Doe, John in-store order Quarterly
111 110 Doe, John online order Quarterly
112 110 Smith, Jane online order Monthly
Each monthly period has a period sequence ID; each period sequence has a parent sequence ID that more broadly organizes the periods in a period table. For example, above, the period seq 109 is March 2017, and is part of the parent seq 106, which is called Quarter 1. See below for an example of what the period table looks like:
PERIODSEQ PERIODNAME PARENTSEQ
106 Quarter 1 105
107 January 2017 106
108 February 2017 106
109 March 2017 106
110 Quarter 2 105
111 April 2017 110
112 June 2017 110
This post was helpful for me, as I had previously been attempting to use a case statement to return multiple values, i.e.
case when payfrequency = 'Quarterly' then add_months(sysdate, -3)
or
case when transactiontable.parentseq = periodtable.parentseq then add_months(sysdate, -3)
but the aforementioned post clearly outlined that a case statement does not return multiple values. I have also tried to use union statements, and having each of the where conditions referencing either Monthly or Quarterly, respectively, but I am still not sure this will pull multiple values:
select * from (
select r.periodseq, r.parentseq, r.name, r.transactiontype, r.payfreq
from transactiontable r
inner join periodtable p
on p.periodseq = r.periodseq
where r.payfreq = 'Monthly'
and r.periodseq = p.periodseq
and p.periodname = 'April 2017' )
UNION ALL
select * from (
select s.periodseq, s.parentseq, s.name, s.transactiontype, s.payfreq
from transactiontable s
inner join periodtable p
on p.periodseq = s.periodseq
where r.payfreq = 'Quarterly'
and s.periodstartdate <= p.startdate
Will this logic work? I only have test data for April 2017, and with this query am still seeing all the transactions I would like to see. I just am not sure this is the ideal solution, or if it will actually work when more periods are added to my test data.
Is there a better way to write the query to get the result I'm looking for? Perhaps I could revise the query to utilize parent seq/period seq more effectively?

Sorting Month And Year Results In Microsoft Access

I have the following table in Microsoft Access
TransactionDate
Market
Details
Opening
Closing
Size
Profit/Loss
I want to run a query that shows the Profit/Loss for each month.
I have been able get a query that returns the information in the following format
TransactionDate By Month Sum Of Sum Of Profit/Loss
April 2014 €1,084.99
April 2015 €674.33
April 2016 €2,057.30
August 2014 €237.59
August 2015 -€267.82
December 2014 €375.88
December 2015 -€1,161.97
February 2015 -€603.87
February 2016 -€124.71
January 2015 €75.11
January 2016 -€1,044.35
But what I want now is for it to display in chronological order as oppose to Alphabetical order.
For example
January 2014
February 2014
March 2014
etc.
I will consider that your TransactionDate field is defined as String
If you want to order by this text field in Access, you will have to use DateValue() function.
That would give:
SELECT TransactionDate FROM yourTable ORDER BY DateValue(TransactionDate)
If your field is already formatted as a Date field, then simply use order by TransactionDate to make it work.

MS Access grouping query spanning start and end dates

I would like to get a running tally of how many widgets were/are rented at any one time, by month, by year. Data is held in an MS Access 2003 db;
Table name: rent_table
Fields:
rentid
startdate
enddate
rentfee
rentcost
bookingfee
Something like; Count number of rentid's that fall between month/year, then group them?
e.g. if a widget was rented from 5th Jan 2014 to 8th April 2014 it would appear as a count in Jan, Feb, Mar and April tally's.
Many thanks.
EDIT
More details (sorry);
Access db is fronted by classic ASP.
If possible I don't want to create any new tables.
No input is required in order to run the report.
There are around 350-400 widgets that could be rented at any one time.
Each widget is rented exclusively.
Report output example;
Month | Year | NumRented
Jan 2014 86
Feb 2014 113
...
Can a query pick up dates within dates? So literally do a count of the table where date >Dec 31st 2013 AND <1st Feb 2014 (to grab a count for all of January 2014) and would that include the example of the rent starting on the 5th Jan? So I could just do twelve counts for each year?
create a calendar table, e.g.
table = cal_yyyymm with one column dt_yyyymm as numeric field
populate the table with ... say 5 or 10 years of data
201401 201402 201403 ... 60 or 120 rows, a small table
make a sql
Select
dt_yyyymm,
count(*) as cnt
From cal_yyyymm
Left Join rent_table
On format(startdate,"yyyymm") >= dt_yyyymm
And dt_yyyymm >= format(enddate,"yyyymm")
think about the complications in the data -- --
widget was rented from 5th Jan 2014 to 8th Jan 2014
and again rented from 11th Jan 2014 to 21st Jan 2014
does this count at 1 or 2 in the month?
if it is 1, then the sql gets more complicated because
the rent_table first needs to have its dates converted
to yyyymm format, and second needs to be de-duped on rentid,
and third then joined to cal_ On the dates...