I want to fetch this data year wise - sql

Select
CIDetail.Itemname,
sum(CIDetail.TaxAmount+ CIDetail.LineAmount) As [TotalAmount]
From
CIDetail (Nolock)
INNER JOIN CIHeader On CIDetail.InvoiceNo= CIHeader.InvoiceNo
Where
CIHeader.InvoiceDate Between '2010-04-01' AND '2014-04-01'
Group By
CIDetail.Itemname

Have a derived table where you use ANSI SQL's EXTRACT to get the year part out of the date, and also add the amounts together. At main level you do GROUP BY both Itemname and year:
Select Itemname, "year", SUM(Amount) as TotalAmount
from
(
CIDetail.Itemname,
extract(year from CIHeader.InvoiceDate) as "year",
CIDetail.TaxAmount + CIDetail.LineAmount As Amount
From
CIDetail (Nolock)
INNER JOIN CIHeader On CIDetail.InvoiceNo= CIHeader.InvoiceNo
) dt
Group By
Itemname, "year"
No dbms tagged in question, but if your dbms doesn't support EXTRACT, try YEAR(CIHeader.InvoiceDate) for example, or something else.

Add to the query a order by clause. Here as you are saying that you want it by date, I will assume that one itemname has only one InvoiceDate. And thus its max will have the same value. You will have to do it as follows
Select CIDetail.Itemname,
sum(CIDetail.TaxAmount+ CIDetail.LineAmount) As [TotalAmount],
From CIDetail (Nolock) INNER JOIN CIHeader
On CIDetail.InvoiceNo= CIHeader.InvoiceNo
Where CIHeader.InvoiceDate Between '2010-04-01' AND '2014-04-01' Group By
CIDetail.Itemname
Order By max(CIHeader.InvoiceDate) ASC

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

Date field not contained in either an aggregate function or the GROUP BY clause

I am trying to calculate "Month to date" using three joined tables. It always gives me error "not contained in either an aggregate function or the GROUP BY clause" The date field is S.BUS_DAT
I tried many things but always get same error. Any advise
Here is the code I use
SELECT
-- Select from IM_IN
M.ITEM_NO,
M.DESCR,
N.QTY_ON_HND,
M.PRC_1,
N.LST_COST,
N.LST_RECV_DAT,
--Select from IM_ITEM
M.CATEG_COD,
M.ATTR_COD_1,
M.ITEM_VEND_NO,
M.ALT_1_UNIT,
M.ALT_1_NUMER,
M.LST_COST,
count (S.BUS_DAT) AS BUS_DAYS,
**sum (QTY_SOLD) OVER (PARTITION BY Month (S.BUS_DAT))as **MTD****
FROM
dbo.IM_INV N
INNER JOIN dbo.IM_ITEM M
ON
N.ITEM_NO = M.ITEM_NO
INNER JOIN
dbo.PS_TKT_HIST_LIN S
ON
N.ITEM_NO = S.ITEM_NO
Group by
M.ITEM_NO,
M.DESCR,
M.ITEM_VEND_NO,
M.CATEG_COD,
M.ATTR_COD_1,
N.QTY_ON_HND,
N.LST_COST,
N.LST_RECV_DAT,
N.LST_SAL_DAT,
M.ALT_1_UNIT,
M.ALT_1_NUMER,
M.PRC_1,
M.LST_COST
Order by M.ITEM_NO
try to include Month(S.BUS_DAT) into group by as well:
SELECT
M.ITEM_NO,
M.DESCR,
N.QTY_ON_HND,
M.PRC_1,
N.LST_COST,
N.LST_RECV_DAT,
M.CATEG_COD,
M.ATTR_COD_1,
M.ITEM_VEND_NO,
M.ALT_1_UNIT,
M.ALT_1_NUMER,
M.LST_COST,
COUNT(S.BUS_DAT) AS BUS_DAYS,
SUM(QTY_SOLD) OVER(PARTITION BY MONTH(S.BUS_DAT)) AS MTD
FROM dbo.IM_INV N
INNER JOIN dbo.IM_ITEM M ON N.ITEM_NO = M.ITEM_NO
INNER JOIN dbo.PS_TKT_HIST_LIN S ON N.ITEM_NO = S.ITEM_NO
GROUP BY M.ITEM_NO,
M.DESCR,
M.ITEM_VEND_NO,
M.CATEG_COD,
M.ATTR_COD_1,
N.QTY_ON_HND,
N.LST_COST,
N.LST_RECV_DAT,
N.LST_SAL_DAT,
M.ALT_1_UNIT,
M.ALT_1_NUMER,
M.PRC_1,
M.LST_COST,
MONTH(S.BUS_DAT)
ORDER BY M.ITEM_NO;
I believe you want:
sum(sum(QTY_SOLD)) OVER (PARTITION BY Month(S.BUS_DAT)) as MTD
Note: You will still need month(s.bus_dat) in the group by clause.
If you only want the sum for the current month, then you don't want a window function, just conditional aggregation:
sum(case when year(s.bus_dat) = year(getdate()) and month(s.bus_dat) = month(getdate())
then qty_sold
end) as mtd

Summing a column over a date range in a CTE?

I'm trying to sum a certain column over a certain date range. The kicker is that I want this to be a CTE, because I'll have to use it multiple times as part of a larger query. Since it's a CTE, it has to have the date column as well as the sum and ID columns, meaning I have to group by date AND ID. That will cause my results to be grouped by ID and date, giving me not a single sum over the date range, but a bunch of sums, one for each day.
To make it simple, say we have:
create table orders (
id int primary key,
itemID int foreign key references items.id,
datePlaced datetime,
salesRep int foreign key references salesReps.id,
price int,
amountShipped int);
Now, we want to get the total money a given sales rep made during a fiscal year, broken down by item. That is, ignoring the fiscal year bit:
select itemName, sum(price) as totalSales, sum(totalShipped) as totalShipped
from orders
join items on items.id = orders.itemID
where orders.salesRep = '1234'
group by itemName
Simple enough. But when you add anything else, even the price, the query spits out way more rows than you wanted.
select itemName, price, sum(price) as totalSales, sum(totalShipped) as totalShipped
from orders
join items on items.id = orders.itemID
where orders.salesRep = '1234'
group by itemName, price
Now, each group is (name, price) instead of just (name). This is kind of sudocode, but in my database, just this change causes my result set to jump from 13 to 32 rows. Add to that the date range, and you really have a problem:
select itemName, price, sum(price) as totalSales, sum(totalShipped) as totalShipped
from orders
join items on items.id = orders.itemID
where orders.salesRep = '1234'
and orderDate between 150101 and 151231
group by itemName, price
This is identical to the last example. The trouble is making it a CTE:
with totals as (
select itemName, price, sum(price) as totalSales, sum(totalShipped) as totalShipped, orderDate as startDate, orderDate as endDate
from orders
join items on items.id = orders.itemID
where orders.salesRep = '1234'
and orderDate between startDate and endDate
group by itemName, price, startDate, endDate
)
select totals_2015.itemName as itemName_2015, totals_2015.price as price_2015, ...
totals_2016.itemName as itemName_2016, ...
from (
select * from totals
where startDate = 150101 and endDate = 151231
) totals_2015
join (
select *
from totals
where startDate = 160101 and endDate = 160412
) totals_2016
on totals_2015.itemName = totals_2016.itemName
Now the grouping in the CTE is way off, more than adding the price made it. I've thought about breaking the price query into its own subquery inside the CTE, but I can't escape needing to group by the dates in order to get the date range. Can anyone see a way around this? I hope I've made things clear enough. This is running against an IBM iSeries machine. Thank you!
Depending on what you are looking for, this might be a better approach:
select 'by sales rep' breakdown
, salesRep
, '' year
, sum(price * amountShipped) amount
from etc
group by salesRep
union
select 'by sales rep and year' breakdown
, salesRep
, convert(char(4),orderDate, 120) year
, sum(price * amountShipped) amount
from etc
group by salesRep, convert(char(4),orderDate, 120)
etc
When possible group by the id columns or foreign keys because the columns are indexed already you'll get faster results. This applies to any database.
with cte as (
select id,rep, sum(sales) sls, count(distinct itemid) did, count(*) cnt from sommewhere
where date between x and y
group by id,rep
) select * from cte order by rep
or more fancy
with cte as (
select id,rep, sum(sales) sls, count(distinct itemid) did, count(*) cnt from sommewhere
where date between x and y
group by id,rep
) select * from cte join reps on cte.rep = reps.rep order by sls desc
I eventually found a solution, and it doesn't need a CTE at all. I wanted the CTE to avoid code duplication, but this works almost as well. Here's a thread explaining summing conditionally that does exactly what I was looking for.

Trying to create a SQL query

I am trying to create a query that retrieves only the ten companies with the highest number of pickups over the six-month period, this means pickup occasions, and not the number of items picked up.
I have done this
SELECT *
FROM customer
JOIN (SELECT manifest.pickup_customer_ref reference,
DENSE_RANK() OVER (PARTITION BY manifest.pickup_customer_ref ORDER BY COUNT(manifest.trip_id) DESC) rnk
FROM manifest
INNER JOIN trip ON manifest.trip_id = trip.trip_id
WHERE trip.departure_date > TRUNC(SYSDATE) - interval '6' month
GROUP BY manifest.pickup_customer_ref) cm ON customer.reference = cm.reference
WHERE cm.rnk < 11;
this uses dense_rank to determine the order or customers with the highest number of trips first
Hmm well i don't have Oracle so I can't test it 100%, but I believe your looking for something like the following:
Keep in mind that when you use group by, you have to narrow down to the same fields you group by in the select. Hope this helps at least give you an idea of what to look at.
select TOP 10
c.company_name,
m.pickup_customer_ref,
count(*) as 'count'
from customer c
inner join mainfest m on m.pickup_customer_ref = c.reference
inner join trip t on t.trip_id = m.trip_id
where t.departure_date < DATEADD(month, -6, GETDATE())
group by c.company_name, m.pickup_customer_ref
order by 'count', c.company_name, m.pickup_customer_ref desc

Incorrect sum when I join a second table

This is the first time I ask for your help,
Actually I have to create a query, and did a similar example for it. I have two tables,
Report (ReportID, Date, headCount)
Production(ProdID, ReportID, Quantity)
My question is using this query, I get a wrong result,
SELECT
Report.date,
SUM(Report.HeadCount) AS SumHeadCount,
SUM(Production.Quantity) AS SumQuantity
FROM
Report
INNER JOIN
Production ON Report.ReportID = Production.ReportID
GROUP BY
Date
ORDER BY
Date
I guess some rows are being counted more than once, could you please give me a hand?
EDIT
if i run a query to get a sum of headcount grouped by day, I get:
date Headcount
7/2/2012 1843
7/3/2012 1802
7/4/2012 1858
7/5/2012 1904
also for Production Qty I get:
2012-07-02 8362
2012-07-03 8042
2012-07-04 8272
2012-07-05 9227
but when i combine the both queries i get i false one, i expect on 2 july 8362 qty against 1843, but i get:
day TotalHeadcount totalQty
7/2/2012 6021 8362
7/3/2012 7193 8042
7/4/2012 6988 8272
7/5/2012 7197 9227
This may be helpful
SELECT Report.ReportDate,
Sum(Report.HeadCount) AS SumHeadCount,
ProductionSummary.SumQuantity
FROM Report
INNER JOIN (SELECT ReportID,
Sum(Production.Quantity) AS SumQuantity
FROM Production
GROUP BY ReportID) AS ProductionSummary
ON Report.ReportID = ProductionSummary.ReportID
GROUP BY ReportDate
ORDER BY ReportDate
One way of avoiding this (subject to RDBMS support) would be
WITH R
AS (SELECT *,
Sum(HeadCount) OVER (PARTITION BY date) AS SumHeadCount
FROM Report)
SELECT R.date,
SumHeadCount,
Sum(P.Quantity) AS SumQuantity
FROM R
JOIN Production P
ON R.ReportID = P.ReportID
GROUP BY R.date, SumHeadCount
ORDER BY R.date
Group records per date using following
SELECT ReportSummary.ReportDate, SUM(ReportSummary.SumHeadCount) AS SumHeadCount, SUM(ProductionSummary.SumQuantity) AS SumQuantity
FROM
(
SELECT Report.ReportDate, SUM(Report.HeadCount) AS SumHeadCount
FROM Report
GROUP BY Report.ReportDate
) AS ReportSummary
INNER JOIN
(
SELECT Report.ReportDate, Sum(Production.Quantity) AS SumQuantity
FROM Production
INNER JOIN Report
ON Report.ReportID = Production.ReportID
GROUP BY Report.ReportDate
) AS ProductionSummary
ON ReportSummary.ReportDate = ProductionSummary.ReportDate
GROUP BY ReportSummary.ReportDate
ORDER BY ReportSummary.ReportDate
We have same problem but I solved it. Try this.
SELECT tbl_report.SumHeadCount, tbl_report.date, tbl_production.SumQuantity
FROM
( select date,
SUM(HeadCount) AS SumHeadCount FROM Report GROUP by date)as tbl_report
JOIN
( select SUM(Quantity) AS SumQuantity, date FROM Production GROUP by date)as tbl_production
WHERE tbl_report.date = tbl_production.date