SQL Statement - want daily dates rolled up and displayed as Year - sql

I have two years worth of data that I'm summing up for instance
Date | Ingredient_cost_Amount| Cost_Share_amount |
I'm looking at two years worth of data for 2012 and 2013,
I want to roll up all the totals so I have only two rows, one row for 2012 and one row for 2013. How do I write a SQL statement that will look at the dates but display only the 4 digit year vs 8 digit daily date. I suspect the sum piece of it will be taken care of by summing those columns withe calculations, so I'm really looking for help in how to tranpose a daily date to a 4 digit year.
Help is greatly appreciated.

select DATEPART(year,[Date]) [Year]
, sum(Ingredient_cost_Amount) Total
from #table
group by DATEPART(year,[Date])

Define a range/grouping table.
Something similar to the following should work in most RDBMSs:
SELECT Grouping.id, SUM(Ingredient.ingredient_cost_amount) AS Ingredient_Cost_Amount,
SUM(Ingredient.cost_share_amount) AS Cost_Share_Amount
FROM (VALUES (2013, DATE('2013-01-01'), DATE('2014-01-01')),
(2012, DATE('2012-01-01'), DATE('2013-01-01'))) Grouping(id, gStart, gEnd)
JOIN Ingredient
ON Ingredient.date >= Grouping.gStart
AND Ingredient.date < Grouping.gEnd
GROUP BY Grouping.id
(DATE() and related conversion functions are heavily DB dependent. Some RDBMSs don't support using VALUES this way, although there are other ways to create the virtual grouping table)
See this blog post for why I used an exclusive upper bound for the range.
Using a range table this way will potentially allow the db to use indices to help with the aggregation. How much this helps depends on a bunch of other factors, like the specific RDBMS used.

Related

SQL sum amount that lies between two dates

I have the following table in SQL:
Start - End - Amount **per day**
06.07.2020 10.07.2020 10
08.07.2020 08.07.2020 5
08.07.2020 15.07.2020 20
02.07.2020 06.07.2020 3
Now I want to filter this table by the calendar week. Let's say "where [calendar week] = cw28". cw28 is from the 06th of july to the 12th of july.
With that I'd like to have the sum of the amount of the days that lie between those two dates. One single number.
I'm using MS SQL Server (SQL Express).
I can't figure out how to distinguish (and break down) if one day lays between the two date values or not. And if yes how much I need to sum up.
I tried to make a picture in excel to create a logic from this:
"Logic" in Excel
Can anyone help me with this? :)
Thx and Best!,
Max
Not sure about your exact requirement. But below is the query to get the sum of values between two dates.
select sum(amount_of_days) from table where date_column between '06-JUL-2020' and '07-JUL-2010';
Change the column name and table name according to your requirement

Writing equations in SQL using multiple variables

I'm trying to use data that is labeled by year (2012 - 2016) to calculate CAGR. The data was originally in one column indicating the total population with another column indicating the year. I've isolated the 2012 and 2016 data into two separate columns and am trying to use SQL to calculate the CAGR rate ((data from 2016)/(data from 2012)^(1/4))-1.
Is this the correct way to calculate CAGR/cummulative growth? I've tried simply using the two columns of data but because they are mismatched and have nulls, it doesn't work. Please let me know if you have any ideas.
Compound Annual Growth Rate (CAGR) doesn't really lend itself to what you're trying to do.
Usually this is used when you say, invest $1000 in a fund, and you calculate the annual growth based on the ending value.
Example - if you invest $1000 and in 5 years it's worth $5000:
( 5,000 / 1,000)1/5 - 1 = .37973 = 37.97%
If I was to write that in SQL Server it would be:
SELECT SUM(POWER((5000.0/1000.0),(1.0/5.0))-1.0)
You can replace the 5000 and 1000 to be the specific columns you want to compare, or a range of data you need to compare.
If you elaborate your question I will update this answer.

SQL YTD for previous years and this year

Wondering if anyone can help with the code for this.
I want to query the data and get 2 entries, one for YTD previous year and one for this year YTD.
Only way I know how to do this is as 2 separate queries with where clauses.. I would prefer to not have to run the query twice.
One column called DatePeriod and populated with 2011 YTD and 2012YTD, would be even better if I could get it to do 2011YTD, 2012YTD, 2011Total, 2012Total... though guessing this is 4 queries.
Thanks
EDIT:
In response to help clear a few things up:
This is being coded in MS SQL.
The data looks like so: (very basic example)
Date | Call_Volume
1/1/2012 | 4
What I would like is to have the Call_Volume summed up, I have queries that group it by week, and others that do it by month. I could pull all the dailies in and do this in Excel but the table has millions of rows so always best to reduce the size of my output.
I currently group by Week/Month and Year and union all so its 1 output. But that means I have 3 queries accessing the same table, large pain, very slow not efficient and that is fine but now I also need a YTD so its either 1 more query or if I could find a way to add it to the yearly query that would ideal:
So
DatePeriod | Sum_Calls
2011 Total | 40
2011 YTD | 12
2012 Total | 45
2012 YTD | 15
Hope this makes any sense.
SQL is built to do operations on rows, not columns (you select columns, of course, but aggregate operations are all on rows).
The most standard approach to this is something like:
SELECT SUM(your_table.sales), YEAR(your_table.sale_date)
FROM your_table
GROUP BY YEAR(your_table.sale_date)
Now you'll get one row for each year on record, with no limit to how many years you can process. If you're already grouping by another field, that's fine; you'll then get one row for each year in each of those groups.
Your program can then iterate over the rows and organize/render them however you like.
If you absolutely, positively must have columns instead, you'll be stuck with something like this:
SELECT SUM(IF(YEAR(date) = 2011, sales, 0)) AS total_2011,
SUM(IF(YEAR(date) = 2012, total_2012, 0)) AS total_2012
FROM your_table
If you're building the query programmatically you can add as many of those column criteria as you need, but I wouldn't count on this running very efficiently.
(These examples are written with some MySQL-specific functions. Corresponding functions exist for other engines but the syntax would be a little different.)

Getting the range in SQL when given between

I am wondering if it's possible (without actually parsing the given string) to get the actual range (in terms of days, minutes or seconds) that is specified when you have an SQL statement like
[select 'x'
from dual
where date between to_date('20111113152049')
and to_date('20120113152049')]
I am working on a query where I'm given a string in the form of
"between to_date(A) and to_date(B)"
and would like to get that value in days to compare to a policy we let the user set so they don't enter a date range longer than say a week.
Assuming you're looking for a theoretical answer (that is: don't take this into production) this could work:
Prerequistes:
have three tables: days_seq(day_seq), month_seq(mth_seq) and year_seq(yr_seq)
days has the numbers 1...31, month 1..12, years 2011....?
Use te following query (I used access because I don't have proper RDBMS available here, keep in mind that MS-ACCESS/JET is forgiving in the use of the Dateserial function, that is, it doesn't break when you ask the dateserial for february, 30th, 2012)
SELECT Max(DateSerial(
[year_seq]![yr_seq]
,[month_seq]![mth_seq]
, [days_seq]![day_seq]))
-
Min(DateSerial(
[year_seq]![yr_seq]
,[month_seq]![mth_seq]
,[days_seq]![day_seq])) AS days
FROM days_seq, month_seq, year_seq
WHERE DateSerial(
[year_seq]![yr_seq]
,[month_seq]![mth_seq]
,[days_seq]![day_seq])
BETWEEN #2012-02-1# AND #2012-02-28#
The query basically produces a carthesian product of three tables which generates all possible days in months, months in a year for as many years as you have in the years table.
Bonus:
You could off-course generate a permanent Calendar table as X-Zero suggests.
table calendar([date])
INSERT INTO calendar
SELECT DISTINCT DateSerial(
[year_seq]![yr_seq]
,[month_seq]![mth_seq]
, [days_seq]![day_seq]))
FROM days_seq, month_seq, year_seq
You still have to pick your start year and your end year wisely. According to the Maya's an enddate of december 21st, 2012 will do.

Sql Queries for finding the sales trend

Suppose ,I have a table which has all the billing records. Now I want to see the sales trend for a user given time duration group by each 3 days ...what should be the sql query regarding this?
please help,Otherwise I am gone ...
I can only give a vague suggestion as per the question, however you may want to have a derived column with a standardised date (as per MS date format, just a number per day) that you could then use a modulus (3) on so that days are equal per 3 day period. You can then group and aggregate over this column to get the values for a 3 day period. Obviously to display the date nicely you would have to multiply back and convert your column as well.
Again I'm not sure of the specifics, but I think this general idea could be achieved to get a result (may well not be the best way so it would help to add more to the question...)