Revenue year by year SQL Server query - sql

I have the following query which provides me with the item and item details, values, rate and quantity across each location.
I am trying to get the yearly revenue based on the Start and End Date. Example, if the chosen date was 2013-2015. The final result will create 3 columns one for 2013 revenue, one for 2014 revenue and one for 2015 revenue.
I am a newbie and still not an expert in writing queries, but here is what I have currently:
SELECT
department,
item,
itemdesc,
qty1,
qty2,
rate_1,
rate_2,
SUM(mm.days*mm.rate*mm.qty)
FROM
items it
LEFT JOIN
(SELECT
i.days, i.rate, i.days, ii.todate, ii.itemid
FROM
invoiceofitems ii
JOIN
invoices i on i.id = ii.id
WHERE
ii.todate BETWEEN #StartDate and #EndDate) mm ON mm.itemid = it.itemid
GROUP BY
department,
item,
itemdesc,
qty1, qty2,
rate_1, rate_2
ORDER BY
item
However, this does not provide me with a year to year aggregation of invoice revenue that I require.
I know this is possible to achieve via iterating through this. But how would I accomplish this and where would I start on this?
Would I need to know the start and end date of each year and iterate through that and then add a counter to the year until year= EndDate?
I'm extremely confused. Help would be appreciated.

I hope that PIVOT and YEAR help you to solve this problem (some columns are omitted):
;WITH SRC(department,item, ... , rate_2, yr, calculation) AS
(SELECT it.department, it.item, ..., it.rate_2, YEAR(ii.todate) as yr,
(i.days * i.rate *i.qty) as calculation
FROM items it
LEFT JOIN invoiceofitems ii ON ii.itemid = it.itemid
JOIN invoices i ON i.id = ii.id)
SELECT department,item, ..., [2013],[2014],[2015]
FROM SRC
PIVOT
(SUM(calculation) FOR yr IN ([2013],[2014],[2015])) PVT
The YEAR function returns only 'year' part of your date and makes grouping easier. PIVOT just rotates grouped data from rows to columns.

Related

Joining 2 columns of a subqueried table into SQL

I'm trying to match the inventory for the day to the SKU.
Amazon_orders has the SKUs I want to match
Invhistory2 has the SKU, timestamp date (more than 1, here's the issue), and the inventory quantity
I'm trying to create a subquery that averages the inventory for the day, then join the timestamp and SKU to the SKUs on the amazon orders table. Null values are no issue here.
My code looks like this:
(SELECT AVG(quantity) AS qty FROM `perfect-obelisk-289514.inventory_history.invhistory2`) AS qtyok
FROM `perfect-obelisk-289514.reports.flat_file_orders_by_order_datereport` Amazon_Orders
LEFT JOIN (SELECT AVG(quantity) AS qty, sku, CAST(snapshot_date AS DATE) AS invdate
FROM `perfect-obelisk-289514.inventory_history.invhistory2`
GROUP BY sku, invdate) AS table2
ON (
Amazon_Orders.sku = table2.sku AND CAST(LEFT(Amazon_orders.purchase_date,10) AS DATE) = table2.invdate
)
The issue is that I get the same average for each row, it's not joining the quantity using SKU and date.
As you may notice I'm a beginner, looked thoroughly but can't find the solution, any help is appreciated!
Thanks for the help!
I managed to solve it. My code was redundant, I just needed this join:
LEFT JOIN (SELECT AVG(quantity) AS qty,
sku,
CAST(snapshot_date AS DATE) AS invdate
FROM `perfect-obelisk-289514.inventory_history.invhistory2`
GROUP BY sku, invdate) AS table2
ON
(Amazon_Orders.sku = table2.sku AND CAST(LEFT(Amazon_orders.purchase_date,10) AS DATE) = table2.invdate)
This gives me what I need

SSRS set year variables per record

I need help to create a code to have it display years specified.
User defines years to report: Year1 Year2 Year3
ProductID Year1 data
Year2 data
Year3 data
where even if year 2 has no data like below
ProductID Year1 data
Year2
Year3 data
My current code will show all data that fit the criteria, but will not show Year2 due to no data.
My current code is
select
sales.ProductID, Sales.Trans_Year, Sum(salesQTY) as QTY
from
(select ProductID, Year(Trans_dt) as Trans_Year, salesQTY
from salestable) sales
group by
sales.ProductID, Sales.Trans_Year
My code is inefficient but I did the select twice so that it would group the year on transdate, if any new to make it better would much appreciated.
Hoping to get help to have the following result.
ProductID Year1 QTY
ProductID Year2
ProductID Year3 QTY
Thank you
You can select the years from your table and cross join them to the products to get a matrix of all years and products. The CROSS JOIN will make a record for each year for each product - regardless if the product was sold in that year.
Then LEFT JOIN your sales total. Using a LEFT JOIN will allow the year and product ID from the SALES_YEAR and SALES subqueries to show even if there's none of a product sold in that year.
SELECT PRODUCTS.ProductID, YEARS.SALES_YEAR, SALES.TOTAL_SALES
FROM (
SELECT ProductID
FROM salestable
GROUP BY ProductID
) AS PRODUCTS
CROSS JOIN (
SELECT YEAR(Trans_dt) AS SALES_YEAR
FROM salestable
WHERE YEAR(Trans_dt) IN #YEARS
) AS YEARS
LEFT JOIN (
SELECT ProductID, Year(Trans_dt) as Trans_Year, SUM(salesQTY) AS TOTAL_SALES
FROM salestable
GROUP BY Year(Trans_dt)
) SALES ON SALES.Trans_Year = YEARS.SALES_YEAR AND SALES.ProductID = PRODUCTS.ProductID
Note that this assumes that you sold something every year selected. If the user enter 1905 for the year and there's no data for 1905, that year wouldn't appear. That shouldn't really be an issue though.

simple sql query highest sales

There are 2 tables - Products and Sales
Products
prod_id
prod_nm
Sales
prod_id
cust_id
sls_dt
sls_amt
Write a query selecting ALL the products. For each product show total of sales amounts in the past 30 days or 0 if not sold in 30 day withoug using subqueries.
Since different RDBMS have different date functions, you can filter by date using the following pseudo code - sls_dt > now() - 30.
Im new to sql and im trying it like this as i found this online.
Select prod_id, prod_nm from(
Select sls_amt
From Sales) as t
Where t.rank = 1
However, this isnt' working. Any help is appreciated
Try below:
select p.prod_id,
p.prod_nm,
sum(s.sls_amt)
from products p
left outer join Sales s on p.prod_id = s.prod_id
and s.sls_dt > now() - 30
group by p.prod_id,
p.prod_nm;

SQL Server 2008 R2- Query to get total sales and qty sold by month

I have 2 tables STOCK and ITEMS,
I am trying to get a report showing how total items purchased (ITEMS table- items.quanto), total sales for items(ITEMS table- I assume (items.quanto*items.it_unlist) with description(STOCK table- stock.desc1) by month (ITEMS table-items.odr_date) with classification (which is a field in the STOCK table- stock.assoc).
The owner wants this info for each month for 2011, 2012, and YTD 2013
so total qty sold for item with total sales of that item by month 2011, 2012, 2013 YTD
This is my query
select items.item, items.quanto, SUM(items.QUANTO*items.it_unlist) as [total cost], stock.desc1, items.it_sdate from items
inner join
stock
on
stock.number = items.item
where IT_SDATE between '2011-01-01 00:00:00.0' and '2011-12-31 00:00:00.0'
group by items.item, items.quanto, stock.desc1, items.it_sdate
order by IT_SDATE
I was hoping to get each item totaled sales and qty by month but this is what I figured out on my own…lol
any help is appreciated.
select
item,
right(convert(varchar(8), it_sdate, 3), 5) theMonth,
sum(quanto) totalQuantity,
sum(quanto * it_unlist) totalSales,
max(stock.desc1) descr,
max(stock.assoc) assoc
from
items inner join stock on
items.item = stock.number
where
it_sdate > '2011-01-01'
group by
item,
right(convert(varchar(8), it_sdate, 3), 5)
order by
item,
theMonth
http://sqlfiddle.com/#!3/246d3/18/0
if the item column of the items table is primary key, then you can’t display the each and every item number when you are trying to display the total sales and qty.
And also, the IT_DATE column consists of only one date per month in the table, then only the below query is possible, if not we need to write other query.
if not, you can select.
select i.quanto, sum(QUANTO * it_unlist) as [total list],
s.desc1, i.it_sdate from items i inner join stock s on (s.number = i.item)
where IT_SDATE > 2011-01-01
group by i.it_sdate order by IT_SDATE;

TERADATA: Aggregate across multiple tables

Consider the following query where aggregation happens across two tables: Sales and Promo and the aggregate values are again used in a calculation.
SELECT
sales.article_id,
avg((sales.euro_value - ZEROIFNULL(promo.euro_value)) / NULLIFZERO(sales.qty - ZEROIFNULL(promo.qty)))
FROM
( SELECT
sales.article_id,
sum(sales.euro_value),
sum(sales.qty)
from SALES_TABLE sales
where year >= 2011
group by article_id
) sales
LEFT OUTER JOIN
( SELECT
promo.article_id,
sum(promo.euro_value),
sum(promo.qty)
from PROMOTION_TABLE promo
where year >= 2011
group by article_id
) promo
ON sales.article_id = promo.article_id
GROUP BY sales.article_id;
Some notes on the query:
Both the inner queries return huge number of rows due to large number of articles. Running explain on teradata, the inner queries themselves take very less time, but the join takes a long time.
Assume primary key on article_id is present and both the tables are partitioned by year.
Left Outer Join because second table contains optional data.
So, can you suggest a better way of writing this query. Thanks for reading this far :)
Not really sure how the avg function got into the mix, so I'm removing it.
SELECT article_id,
(SUM(sales_value) - SUM(promo_value)) /
(SUM(sales_qty) - SUM(promo_qty))
FROM (
SELECT
article_id,
sum(euro_value) AS sales_value,
sum(qty) AS sales_qty,
0 AS promo_value,
0 AS promo_qty
from SALES_TABLE sales
where year >= 2011
group by article_id
UNION ALL
SELECT
article_id,
0 AS sales_value,
0 AS sales_qty,
sum(euro_value) AS promo_value,
sum(qty) AS promo_qty
from SALES_TABLE sales
where year >= 2011
group by article_id
) AS comb
GROUP BY article_id;