Combine ContainerID row and add Qty - sql

I want to combine Container ID, Date, and add the Qty. This query shows data at the item level. I want it to print data at the order level and sum the "Qty" column.
I can combine rows using excel & pivot tables, but when I run reports for over 3 months, I run out of rows in excel, so I break it up into smaller chunks and add the results. Tedious. There has to be an easier way.
What I am getting:
OrderDate ContainerID Qty
2019-06-03 104922434 1
2019-06-03 104922434 1
2019-06-01 104934958 1
2019-06-01 104934958 1
2019-06-01 104934958 1
What I want:
OrderDate ContainerID Qty
2019-06-03 104922434 2
2019-06-01 104934958 3
My current query:
select
convert(date,oh.ShipTime) as 'OrderDate',
p.ContainerID,
cc.Qty
from dmhost.tblOrderHeader oh
join dmhost.tblContainer c on oh.OrderHeaderID = c.OrderHeaderID
join dmhost.tblPackage p on c.ContainerID = p.ContainerID
join dmhost.tblContainerContents cc on c.ContainerID = cc.ContainerID
join dmhost.tblItemMaster im on im.ItemMasterID = cc.ItemMasterID
where (oh.ShipTime between '06/1/2019' and '07/1/2019')
and (BusinessUnitCode like '03'or BusinessUnitCode like '04')
and cc.Qty <> 0
order by p.ContainerID
I appreciate the help.

You can use SUM and GROUP BY:
select
convert(date,oh.ShipTime) as 'OrderDate',
p.ContainerID,
SUM(cc.Qty) Qty
from dmhost.tblOrderHeader oh
join dmhost.tblContainer c on oh.OrderHeaderID = c.OrderHeaderID
join dmhost.tblPackage p on c.ContainerID = p.ContainerID
join dmhost.tblContainerContents cc on c.ContainerID = cc.ContainerID
join dmhost.tblItemMaster im on im.ItemMasterID = cc.ItemMasterID
where (oh.ShipTime between '06/1/2019' and '07/1/2019')
and (BusinessUnitCode like '03'or BusinessUnitCode like '04')
and cc.Qty <> 0
group by
convert(date,oh.ShipTime),
p.ContainerID
order by ContainerID

Related

SQL query for most recent date

I'm trying to query to only pull the most recent sale date but keep the unique value of "strap". This is the query result I have.
nh_cd strap dor_cd acreage sqft sale date reception_num price asd_val rea_cd
178.00 R0000001 AG 4.7160 205443 2019-07-11 00:00:00.000 3723615 890000 200 05
178.00 R0000001 AG 4.7160 205443 2020-05-29 00:00:00.000 3787823 880000 200 40
205.00 R0022222 AGRES 5.8030 252771 2019-06-10 00:00:00.000 3718473 647500 520200 40
This is what I've built so far, but it doesn't give me my desired result of a recent date.
SELECT distinct
parcel.nh_cd
,sales.strap
,parcel.dor_cd
,detail.acreage
,detail.sqft
,max(sales.dos)
,sales.reception_num
,sales.price
,parcel.asd_val
,sales.rea_cd
,sales.qu_flg
,sales.valid_cd
,sales.vi
,site.str_num
,site.str_pfx
,site.str
,site.str_sfx
,site.city
,parcel.status_cd
,strap_idx.folio
FROM detail INNER JOIN parcel ON parcel.strap = detail.strap
INNER JOIN sales ON parcel.strap = sales.strap
INNER JOIN site ON parcel.strap = site.strap
INNER JOIN strap_idx ON parcel.strap = strap_idx.strap
INNER JOIN lnd_a ON parcel.strap = lnd_a.strap
WHERE lnd_a.st_use_cd IN ('4117','4127','4137','4147','4167','4177','4180')
AND parcel.dor_cd LIKE 'AG%'
AND parcel.status_cd = 'A'
AND (sales.price > '0')
AND (site.ln_num = '1')
AND (sales.dos>='07/01/2018')
AND (sales.dos<='08/24/2020')
GROUP by parcel.nh_cd
,sales.strap
,parcel.dor_cd
,detail.acreage
,detail.sqft
,sales.dos
,sales.reception_num
,sales.price
,parcel.asd_val
,sales.rea_cd
,sales.qu_flg
,sales.valid_cd
,sales.vi
,site.str_num
,site.str_pfx
,site.str
,site.str_sfx
,site.city
,parcel.status_cd
,strap_idx.folio
This is the result I want
nh_cd strap dor_cd acreage sqft sale date reception_num price asd_val rea_cd
178.00 R0000001 AG 4.7160 205443 2020-05-29 00:00:00.000 3787823 880000 200 40
205.00 R0022222 AGRES 5.8030 252771 2019-06-10 00:00:00.000 3718473 647500 520200 40
How would I go about doing this?
You can ROW_NUMBER() it
SELECT *
FROM (
SELECT distinct parcel.nh_cd
,sales.strap
,parcel.dor_cd
,detail.acreage
,detail.sqft
,sales.dos
,sales.reception_num
,sales.price
,parcel.asd_val
,sales.rea_cd
,sales.qu_flg
,sales.valid_cd
,sales.vi
,site.str_num
,site.str_pfx
,site.str
,site.str_sfx
,site.city
,parcel.status_cd
,strap_idx.folio
, ROW_NUMBER() OVER(PARTITION BY parcel.nh_cd, sales.strap ORDER BY sales.dos DESC) AS rn
FROM detail INNER JOIN parcel ON parcel.strap = detail.strap
INNER JOIN sales ON parcel.strap = sales.strap
INNER JOIN site ON parcel.strap = site.strap
INNER JOIN strap_idx ON parcel.strap = strap_idx.strap
INNER JOIN lnd_a ON parcel.strap = lnd_a.strap
WHERE lnd_a.st_use_cd IN ('4117','4127','4137','4147','4167','4177','4180')
AND parcel.dor_cd LIKE 'AG%'
AND parcel.status_cd = 'A'
AND (sales.price > '0')
AND (site.ln_num = '1')
AND (sales.dos>='07/01/2018')
AND (sales.dos<='08/24/2020')
) t
WHERE rn = 1

Advanced SQL: Sum of sales between a date range

I'm trying to get the sum of sales for a specific product between a date range. Unfortunately, the sum of sales from the results for both dates are the same. By right the total sales on 2019/01/01 is 5000 and the total sales on following day 2019/01/02 is 3000. The results showed total sales which is 8000 for both days. Which is wrong. Any expert can help to improve is this query?
Declare #BusinessDate datetime ='2019-01-01'
Declare #end datetime ='2019-01-02'
DECLARE #StoreId int = 100
SELECT [Terminals].[Id] AS [TerminalId],
[Terminals].[StoreId],
[EOD].[Id] AS [EODId],
SUM([Sales].[SalesAmount]) AS [SalesAmount],
[EOD].BusinessDate
FROM [CEPP]..[Stores] WITH (NOLOCK)
INNER JOIN [CEPP]..[Terminals] WITH (NOLOCK)
ON [Stores].[Id] = [Terminals].[StoreId]
AND [Terminals].[MWorkFlowStatusId] = 2
AND ([Terminals].[MStatusId] = 1
OR ([Terminals].[MStatusId] = 0
AND [Terminals].[SuspendedDate] > #BusinessDate ))
LEFT JOIN [EndOfDays] AS [EOD] WITH (NOLOCK)
ON [Terminals].[Id] = [EOD].[TerminalId]
AND [EOD].[BusinessDate] >= #BusinessDate and [EOD].[BusinessDate]<=#end
CROSS APPLY (
SELECT SUM([Products].[Deno]) AS [SalesAmount]
FROM [SalesOrders] AS [SO] WITH (NOLOCK)
INNER JOIN [SalesTransactions] AS [ST] WITH (NOLOCK)
ON [SO].[Id] = [ST].[SalesOrderId]
LEFT JOIN [VoidOrders] AS [VO] WITH (NOLOCK)
INNER JOIN [VoidTransactions] AS [VT] WITH (NOLOCK)
ON [VO].[Id] = [VT].[VoidOrderId]
ON [SO].[DealerId] = [VO].[DealerId]
AND [SO].[StoreId] = [VO].[StoreId]
AND [SO].[TerminalId] = [VO].[TerminalId]
AND [ST].[ProductId] = [VT].[ProductId]
AND [ST].[SerialNo] = [VT].[SerialNo]
AND [ST].[BusinessDate] = [VT].[BusinessDate]
AND [VT].[MVoidTypeId] = 1
INNER JOIN [CEPP].[dbo].[Products] WITH (NOLOCK)
ON [ST].[ProductId] = [Products].[Id]
WHERE [EOD].[Id] IS NOT NULL
AND [VT].[SerialNo] IS NULL
AND [SO].[TerminalId] = [Terminals].[Id]
AND [ST].[BusinessDate] >= #BusinessDate and [ST].[BusinessDate] <= #end
) AS [Sales]
WHERE [Stores].[DealerId] = 1 AND (#StoreId IS NULL OR [Terminals].[StoreId] = #StoreId)
GROUP BY [Terminals].[Id], [Terminals].[StoreId], [EOD].[Id], [Stores].[Code], [Terminals].[Code],[EOD].BusinessDate
ORDER BY ISNULL([EOD].[Id], 0), [Stores].[Code], [Terminals].[Code]
The unexpected results I got is :
TerminalId StoreId EODId SalesAmount BusinessDate
21598 100 5427531 8000.00 2019-01-01 00:00:00.000
21598 100 5427532 8000.00 2019-01-02 00:00:00.000
The results should be like this:
TerminalId StoreId EODId SalesAmount BusinessDate
21598 100 5427531 5000.00 2019-01-01 00:00:00.000
21598 100 5427532 3000.00 2019-01-02 00:00:00.000
From what I can see at a glance and without test data, is that the SUM([Products].[Deno]) is being performed in the CROSS APPLY irrespective of any GROUP BY you have in the outer query. Hence why you're getting SUM([Sales].[SalesAmount]) to equal 8000 for each output row.
Refactor the CROSS APPLY subquery to aggregate SUM([Products].[Deno]) with respect to a GROUP BY and join back to the main table by the GROUP BY predicates to your outer query.
AND [EOD].[BusinessDate] >= #BusinessDate and [EOD].[BusinessDate]<=#end
This part looks very suspicious to me. I think it should be something like
[EOD].[BusinessDate] = [Sales].[Date]
If that does not resolve your problem, please provide us with scripts for creation of tables and test data. That way it's much easier to investigate query.

How to us Group By in SQL with a JOIN

I am wondering if anyone could help me. I trying to write a query which will group all the order detail lines to each product.
SELECT
Line.NetAmount, Line.QtyDespatch, Line.QtyOrder,
Line.Price, Line.Price * Line.QtySent AS 'Value'
FROM dbo.orderdetails line
LEFT JOIN
(
SELECT products.ProductID, products.CompanyID AS StockCompanyID,
products.StockCode FROM dbo.products
)
Stock ON Line.ProductID = products.ProductID AND products.StockCompanyID = Line.CompanyID
WHERE Line.CompanyID = 1
ORDER BY Stock.StockID ASC
The results I am getting are for each order details line individually but I want to group-by the each product id and have (Line.Price * Line.QtySent) as sum for each product and show each product once.
The result I am getting are
PID Net sent qty Price Value
39044 12 0 5 2.4 0
39044 12 0 5 2.4 0
39044 12 0 5 2.4 0
39044 12 0 5 2.4 0
But I do not want to get it for each line but a cumulative value for all line by product. Basically cumulative totals for each product
You would need to group by the ProductId and then sum the Line.Price multiplied by the Line.QtySent. You would want something like this:
SELECT p.ProductID, SUM(Line.Price * Line.QtySent) AS 'Value'
FROM dbo.orderdetails line
LEFT JOIN dbo.products p ON
Line.ProductID = p.ProductID AND p.CompanyID = Line.CompanyID
WHERE Line.CompanyID = 1
GROUP BY p.ProductID
Your description sounds like this query:
SELECT od.ProductId, SUM(od.Price * od.QtySent) as total
FROM dbo.orderdetails od
GROUP BY od.ProductId;

Avoid third table multiplying results

I have three tables.
Defect: Main table used to store defects found.
FollowUp: Table that stores followups to a specific Defect.
Defect_Attach: Related table used all photo attachments for Defects and FollowUps.
How can I get dates for all photo attachments?
Some of these photos were taken for a defect, then at a later date, more photos were related to the defect during a followup.
The results I'm trying to get would look something like this:
or
So far my query looks like this:
SELECT d.GUID
,p.ATTACHMENTID
,p.REL_OBJECTID
,p.CONTENT_TYPE
,p.ATT_NAME
,p.DATA_SIZE
,d.DateObserved as 'Defect Date'
--,f.DateObserved as 'FollowUp Date'
FROM [ECIMUSR].[DEFECT__ATTACH] p
LEFT OUTER JOIN ECIMUSR.DEFECT d on d.ObjectID = p.REL_OBJECTID
--LEFT JOIN ECIMUSR.FOLLOWUP f on f.DefectGUID = d.GUID
WHERE
d.GUID = '{E511EA70-F5E5-11E4-8189-6C3BE50ED71F}'
ORDER BY [Defect Date]
But as soon as I try joining my third table (FOLLOWUP), my results multiply.
UPDATE:
Results:
SELECT p.ATT_NAME
,d.DateObserved as 'Defect Date'
--,f.DateObserved as 'FollowUp Date'
FROM [ECIMUSR].[DEFECT__ATTACH] p
LEFT OUTER JOIN ECIMUSR.DEFECT d on d.ObjectID = p.REL_OBJECTID
--LEFT JOIN ECIMUSR.FOLLOWUP f on f.DefectGUID = d.GUID
WHERE
d.GUID = '{E511EA70-F5E5-11E4-8189-6C3BE50ED71F}'
ORDER BY [Defect Date]
Joining THIRD Table:
SELECT p.ATT_NAME
,d.DateObserved as 'Defect Date'
,f.DateObserved as 'FollowUp Date'
FROM [ECIMUSR].[DEFECT__ATTACH] p
LEFT OUTER JOIN ECIMUSR.DEFECT d on d.ObjectID = p.REL_OBJECTID
LEFT JOIN ECIMUSR.FOLLOWUP f on f.DefectGUID = d.GUID
WHERE
d.GUID = '{E511EA70-F5E5-11E4-8189-6C3BE50ED71F}'
ORDER BY [Defect Date]
SELECT
d.DateObserved AS defect_date,
p.ATT_NAME AS photo_name,
f.DateObserved AS follow_up_date
FROM
(
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY REL_OBJECTID
ORDER BY ATT_NAME) AS ordinal
FROM
ECIMUSR.DEFECT__ATTACH
)
p
FULL OUTER JOIN
(
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY DefectGUID
ORDER BY DateObserved) AS ordinal
FROM
ECIMUSR.FOLLOWUP
)
f
ON f.DefectGUID = p.REL_OBJECTID
AND f.ordinal = p.ordinal
RIGHT JOIN
ECIMUSR.DEFECT d
ON d.ObjectID = COALESCE(f.DefectGUID, p.REL_OBJECTID)
Would give something like...
defect_date | photo_name | follow_up_date
-------------+-----------------------------+----------------
2014-12-19 | photo1.jpg | 2015-01-16
2014-12-19 | PhotoFollowUp1_20150117.jpg | 2015-03-19
2014-12-19 | PhotoFollowUp1_20150324.jpg | 2015-04-17
2014-12-19 | PhotoFollowUp1_20150417.jpg | NULL
2014-12-19 | PhotoFollowUp2_20150324.jpg | NULL
The photo names and the follow up dates have nothing to do with each others. they're just in alphabetical order with gaps if one list is longer than the other.

Sum of a subquery?

Background:
We are doing a price adjustment in our database. The price adjustment is based on the bill of materials, and what each materials' new cost is. So I have to select the item from the item table, its BOM, and the new price table, and adjust the price based on the total of the materials it takes to make each item. Items are comprised of varying quantities of varying materials, so the master query will call this subquery to get the total adjustment:
select
ta.Code,
ta.Quantity,
(select tb.cost - tb.NewCost * ta.Quantity ) as BOMEffect
from BOM TA
inner join ITEM TC on tC.ItemCode = tA.Father
inner join NewPriceTable TB on tA.Code = tB.Item
where TA.Father = '100-01'
and tc.PriceList = 3
order by ta.Father
Which gives me the results (this is all of the materials of one item, quantity of each material, and the price adjustment):
Code Quantity BOMEffect
D .003 56.000000 -95.08
D .004 28.000000 -62
D .005 20.000000 -54.6
d .006 2.000000 -3.3
D .01 2.000000 -5.5
D .015 4.000000 -25.52
D .02 4.000000 -34
All I need from this query is the total BOMEffect (-280). But if I just replace the select statement with:
select
sum((select tb.cost - tb.NewCost * ta.Quantity )) as BOMEffect
from BOM TA
inner join ITEM TC on tC.ItemCode = tA.Father
inner join NewPriceTable TB on tA.Code = tB.Item
where TA.Father = '100-01'
and tc.PriceList = 3
order by ta.Father
I get:
Cannot perform an aggregate function on an expression containing an aggregate or a subquery.
I know what it's saying, but I don't know any other way to do it. How else can I get this total? This is a small subquery that is part of a larger query, so I only need to return the total. I could probably use a view or a temp table, but I would like to stay away from that if possible.
remove the select inside the sum and order by
select
sum(tb.cost - tb.NewCost * ta.Quantity) as BOMEffect
from BOM TA
inner join ITEM TC on tC.ItemCode = tA.Father
inner join NewPriceTable TB on tA.Code = tB.Item
where TA.Father = '100-01'
and tc.PriceList = 3
If you want to include Code and Quantity you would have to include those in the GROUP BY clause:
select
ta.Code,
ta.Quantity,
sum(tb.cost - tb.NewCost * ta.Quantity) as BOMEffect
from BOM TA
inner join ITEM TC on tC.ItemCode = tA.Father
inner join NewPriceTable TB on tA.Code = tB.Item
where TA.Father = '100-01'
and tc.PriceList = 3
GROUP BY ta.Code, ta.Quantity