Regarding last year value from the date field - sql

I have a table with the columns Sales_Date and Sales. I am looking for a solution to get Sales for the last year from the Sales_Date Column. Sales_Date column has values from the year 2015 onwards.
For example:
Sales_Date
Sales
1/1/2016
$25
1/8/2016
$57
1/1/2015
$125
1/8/2015
$21
I am looking for the below result set:
Sales_Date
Sales
LYear_Sales_Date
LYear_Sales
1/1/2016
$25
1/1/2015
$125
1/8/2016
$57
1/8/2015
$21

Filter all data to this year (WHERE YEAR(Sales.Sales_Date) = 2016).
LEFT JOIN to the same table, combining each date with the same date one year prior (Sales LEFT JOIN Sales AS Sales_LastYear ON Sales_LastYear.Sales_Date = DATEADD(year, -1, Sales.Sales_Date)).
SELECT the fields that you want (SELECT Sales.Sales_Date, Sales_LastYear.Sales_Date AS LYear_Sales_Date, ...).
Replace the LEFT JOIN with an INNER JOIN, if you want only those records that have a matching last-year record.

Seems like LAG would work here. Assuming you are always wanting the for the same (day and) month:
WITH CTE AS(
SELECT Sales_Date,
Sales,
LAG(Sales_Date) OVER (PARTITION BY DAY(Sales_Date), MONTH(Sales_Date) ORDER BY YEAR(Sales_Date)) AS LYear_Sales_Date,
LAG(Sales) OVER (PARTITION BY DAY(Sales_Date), MONTH(Sales_Date) ORDER BY YEAR(Sales_Date)) AS LYear_Sales
FROM dbo.YourTable)
SELECT Sales_Date,
Sales,
LYear_Sales_Date,
LYear_Sales
FROM CTE
WHERE Sales_Date >= '20160101'
AND Sales_Date < '20170101';

Related

How to resolve SQL SUM not working correctly?

I have an SQL data table called sales that records product, quantity sold, unit price, and the date of the sale. I would like to create a view with monthly sales for chairs from 2000-2010. That is, for every unique month and year pair I would like to sum up quantity * unit_price where the product = "CHAIR". My attempt is the following:
CREATE VIEW MONTHLY_SALES(product, monthly_sales, month, year) AS (
SELECT product, SUM(quantity * unit_price) AS monthly_sales,
TO_CHAR(sale_date, 'Month') AS month, EXTRACT(YEAR FROM sale_date) AS year
FROM sales
WHERE sale_date BETWEEN '2000-01-01' AND '2010-12-31' AND product = 'CHAIR'
GROUP BY quantity, unit_price, article, sale_date);
SELECT *
FROM MONTHLY_SALES;
I would expect to sum over the same month and year and get something like:
product | monthly_sales | month | year
Chair 100 January 2001
Chair 110 February 2001
Chair 120 March 2001
Chair 300 April 2001
But I'm seeing different monthly_sales for the same month-year pairs so I don't know why the SUM isn't working. Any assistance to fix this would be much appreciated.
===============================================================
Sample Data:
product | quantity | unit_price | sales_date
Chair 1 40 2001-01-01
Chair 3 40 2001-01-02
Chair 4 40 2001-02-01
Chair 1 40 2001-02-05
Expected Output:
product | monthly_sales | month | year
Chair 160 January 2001
Chair 200 February 2001
SELECT product, SUM(quantity * unit_price) AS monthly_sales,
EXTRACT(MONTH from sales_date) AS month, EXTRACT(YEAR FROM sales_date) AS year
FROM sales
WHERE sales_date BETWEEN '2000-01-01' AND '2010-12-31' AND product = 'CHAIR'
group by product, year, month
I've created a fiddle
Your group by is wrong - you're not grouping by product, month and year. What you're asking is "every time you see a change in any of quantity, price, article (whatever that is) and date, perform the sum". That will create lots of duplicates (if you have two sales in a given year/month combination, your group by says "create a new row because you've seen a change in sales date).
You are grouping by the sales date, instead of the month and year of the sale. You will get one record per sales_date instead of one record per month. This example will work in your case:
CREATE VIEW MONTHLY_SALES(product, monthly_sales, month, year) AS (
SELECT product, SUM(quantity * unit_price) AS monthly_sales,
TO_CHAR(sale_date, 'Month') AS month, EXTRACT(YEAR FROM sale_date) AS year
FROM sales
WHERE sale_date BETWEEN '2000-01-01' AND '2010-12-31' AND product = 'CHAIR'
GROUP BY article, TO_CHAR(sale_date, 'Month'), EXTRACT(YEAR FROM sale_date));
SELECT *
FROM MONTHLY_SALES

Sales amounts of the top n selling vendors by month in bigquery

i have a table in bigquery like this (260000 rows):
vendor date item_price
x 2021-07-08 23:41:10 451,5
y 2021-06-14 10:22:10 41,7
z 2020-01-03 13:41:12 74
s 2020-04-12 01:14:58 88
....
exactly what I want is to group this data by month and find the sum of the sales of only the top 20 vendors in that month. Expected output:
month sum_of_only_top20_vendor's_sales
2020-01 7857
2020-02 9685
2020-03 3574
2020-04 7421
.....
Consider below approach
select month, sum(sale) as sum_of_only_top20_vendor_sales
from (
select vendor,
format_datetime('%Y%m', date) month,
sum(item_price) as sale
from your_table
group by vendor, month
qualify row_number() over(partition by month order by sale desc) <= 20
)
group by month
Another solution that potentially can show much much better performance on really big data:
select month,
(select sum(sum) from t.top_20_vendors) as sum_of_only_top20_vendor_sales
from (
select
format_datetime('%Y%m', date) month,
approx_top_sum(vendor, item_price, 20) top_20_vendors
from your_table
group by month
) t
or with a little refactoring
select month, sum(sum) as sum_of_only_top20_vendor_sales
from (
select
format_datetime('%Y%m', date) month,
approx_top_sum(vendor, item_price, 20) top_20_vendors
from your_table
group by month
) t, t.top_20_vendors
group by month

Query two unbalanced tables

Sum across two tables returns unwanted Sum from one table multiplied by the number of rows in the other
I have 1 table with Actual results recorded by date and the other tables contains planned results recorded by month.
Table 1(Actual)
Date Location Amount
01/01/2019 Loc1 1000
01/02/2019 Loc1 700
01/01/2019 Loc2 7500
01/02/2019 Loc2 1000
02/01/2019 Loc1 500
Table 2(Plan)
Year Month Location Amount
2019 1 Loc1 1500
2019 1 Loc2 8000
2019 2 Loc1 800
I have tried various differed Joins using YEAR(Table1.date) and Month(table1.date) and grouping by
Month(Table1.Date) but I keep running into the same problem where the PlanAmount is multiplied by however many rows in the Actual table...
in the example of loc1 for Month 1 below I get
Year Month Location PlanAmount ActualAmount
2019 1 Loc1 3000 1700
I would like to return the below
Year Month Location PlanAmount ActualAmount
2019 1 Loc1 1500 1700
2019 1 Loc2 8000 8500
2019 2 Loc1 800 500
Thanks in advance for any help
D
You can do this with a full join or union all/group by:
select yyyy, mm, location,
sum(actual_amount) as actual_amount,
sum(plan_amount) as plan_amount
from ((select year(date) as yyyy, month(date) as mm, location,
amount as actual_amount, 0 as plan_amount
from actual
group by year(date) as yyyy, month(date) as mm, location
) union all
(select year, month, location,
0 as actual_amount, amount as plan_amount
from actual
group by year, month, location
)
) ap
group by yyyy, mm, location;
This ensures that you have rows, even when there are no matches in the other table.
To get the required results you need to group the first table on year of date, month of date and location and need to select the columns year, month, location and sum of amount from group after that you need to join that resultant r
SELECT
plans.year,
plans.month,
plans.location,
plans.plan_amount,
grouped_results.actual_amount
FROM plans
INNER JOIN (
SELECT
datepart(year, date) AS year,
datepart(month, date) AS month,
location,
SUM(amount) AS actual_amount
FROM actuals
GROUP BY datepart(year, date), datepart(month, date), location
) as grouped_results
ON
grouped_results.year = plans.year AND
grouped_results.month = plans.month AND
grouped_results.location = plans.location
I think the problem is that you are using sum(PlanTable.Amount) when grouping. Try using max(PlanTable.Amount) instead.
select
p.Year,
p.Month,
p.Location,
sum(a.Amount) as actual_amount,
max(p.Amount) as plan_amount
from
[Plan] p left join Actual a
on year(a.date) = p.year
and month(a.date) = p.Month
and a.Location = p.Location
group by
p.year,
p.month,
p.Location
SQL Fiddle
get year and month from date and use them in join , most dbms has year and month functions you can use according to your DBMS
select year(t1.date) yr,month(t1.date) as monthofyr ,t1.Location,
sum(t1.amount) as actual_amoun,
sum(t2.amount) as planamount
from table1 t1 left join table2 t2 on
month(t1.date)= t2.Month and t1.Location=t2.Location
and year(t1.date)=t2.year
group by year(t1.date) ,month(t1.date),Location

SQL Count Entries for each Month of the last 6 Months

I got a problem while trying to count the entries that were created in a month for the last 6 months.
The table looks like this:
A B C D
Year Month Startingdate Identifier
-----------------------------------------
2019 3 2019-03-12 OAM_1903121
2019 2 2019-03-21 OAM_1902211
And the result should look like:
A B C
Year Month Amount of orders
---------------------------------
2019 3 26
2019 2 34
This is what I have so far, but it doesn't get me the proper results:
SELECT year, month, COUNT(Startingdate) as Amount
FROM table
WHERE Startingdate > ((TRUNC(add_months(sysdate,-3) , 'MM'))-1)
GROUP BY year, month
I have not tested it, but it should work:
select year, month, count(Stringdate) as Amount_of_order
from table
where Stringdate between add_months(sysdate, -6) and sysdate
group by year, month;
Let me know.
Try that :
SELECT YEAR(Startingdate) AS [Year], MONTH(Startingdate) AS [Month], COUNT(*) AS Amount
FROM table
WHERE Startingdate > DATEADD(MONTH, -6, GETDATE())
GROUP BY YEAR(Startingdate), MONTH(Startingdate)
ORDER BY YEAR(Startingdate), MONTH(Startingdate) DESC
I think your issue is the filtering. If so, this should handle the most recent six full months:
SELECT year, month, COUNT(*) as num_orders
FROM table
WHERE Startingdate >= TRUNC(add_months(sysdate, -6) , 'MM')
GROUP BY year, month;

SQL Sum by week from daily table

I have a table with sales for products.
The sales are per day. like
product date sales
1 '2013-11-01' 100
1 '2013-11-02' 423
1 '2013-11-03' 700
1 '2013-11-04' 233
2 '2013-11-01' 623
2 '2013-11-02' 451
2 '2013-11-03' 9000
I want to get a query which will show me the week over week sum of sales
So something like:
product week ending sales
1 '2013-11-01' 10000
1 '2013-11-08' 15000
2 '2013-11-01' 4900
2 '2013-11-08' 30000
I'm not sure how I get this weekly groups when summing up.
I'm using teradata
If you are using Teradata 14 you can leverage the DayNumber_Of_Week() function in the database TD_SYSFNLIB:
SELECT s.Product
, s.Date + (7-DayNumber_Of_Week(s.date)) AS WeekEndingDate /* Saturday */
, SUM(s.Sales) AS Sales
FROM sales AS S
GROUP BY 1,2;
This should work in Teradata 13.10 as well.
Using Sys_Calendar:
SELECT s.Product
, s.DATE + (7-c.Day_Of_Week) AS WeekEndingDate /* Saturday */
, SUM(s.Sales) AS Sales
FROM sales AS S
INNER JOIN
Sys_Calendar.Calendar c
ON S.date = c.calendar_date
GROUP BY 1,2;
I know very little about TERADATA, but I believe you can leverage the sys_calendar.calendar table, something like:
SELECT s.Product, c.week_of_year, SUM(s.sales) AS Sales
FROM sales AS s
JOIN sys_calendar.calendar as C
ON s.date = c.date
You'd need the Year in there as well, so as to not group up week 1 of 2013 with week 1 of 2012.