SQL Query Second sum column squaring results - sql

If I run 2 queries separately I get results like this..
select A.ACTNUMST, sum(B.EXTDCOST) as [IV Total]
from GL00105 A
INNER JOIN SEE30303 B on A.ACTINDX = B.IVIVINDX
group by A.ACTNUMST
Results -
Account No IV Total
2101-00-137 2033.60
4101-00-137 83765.86
6101-00-137 301984.23
Second Query
select A.ACTNUMST as [Account No], SUM(C.PERDBLNC) as [GL Total]
from GL00105 A
LEFT JOIN GL10110 C on A.ACTINDX = C.ACTINDX
group by A.ACTNUMST
Results -
Account No GL Total
2101-00-137 2033.60
4101-00-137 83765.86
6101-00-137 302656.23
I want to be able to join both results together to compare but I believe it is repeating the sum for each line in the GL total and then summing it again, it comes out with large numbers like -
select A.ACTNUMST as [Account No], sum(B.EXTDCOST) as [IV Total], SUM(C.PERDBLNC) as [GL Total]
from GL00105 A
INNER JOIN SEE30303 B on A.ACTINDX = B.IVIVINDX
LEFT JOIN GL10110 C on A.ACTINDX = C.ACTINDX
group by A.ACTNUMST
Results -
Account No IV Total GL Total
2101-00-137 2033.60 14235.20
4101-00-137 83765.86 116350696.20
6101-00-137 301984.23 1612897825.84
When it should be
Results -
Account No IV Total GL Total
2101-00-137 2033.60 2033.60
4101-00-137 83765.86 83765.86
6101-00-137 301984.23 302656.23
Please advise how to use the sum function to get the correct results.

Do you want something like this? Please check and comment if this is not what is expected.
Also please rectify any syntax errors.
SELECT T1.[Account No], T1.[IV Total], T2.[GL Total] FROM
(
select A.ACTNUMST as [Account No], sum(B.EXTDCOST) as [IV Total]
from GL00105 A
INNER JOIN SEE30303 B on A.ACTINDX = B.IVIVINDX
group by A.ACTNUMST
) T1
INNER JOIN
(
select A.ACTNUMST as [Account No], SUM(C.PERDBLNC) as [GL Total]
from GL00105 A
LEFT JOIN GL10110 C on A.ACTINDX = C.ACTINDX
group by A.ACTNUMST
) T2
ON T1.[Account No] = T2.[Account No]
Hope this helps

this can be done with the multiple cte also
with IVTotal as
(
select A.ACTNUMST, sum(B.EXTDCOST) as [IV Total]
from GL00105 A
INNER JOIN SEE30303 B
on A.ACTINDX = B.IVIVINDX
group by A.ACTNUMST
),
GLTotal as
(
select A.ACTNUMST as [Account No], SUM(C.PERDBLNC) as [GL Total]
from GL00105 A
LEFT JOIN GL10110 C
on A.ACTINDX = C.ACTINDX
group by A.ACTNUMST
)
select a.*,b.[GL Total]
from IVTotal a ,GLTotal b
where a.ACTNUMST = b.aCTNUMST

Related

Only display the day with the max profit per store

Only display the day with the max profit per store in SQL Server
For example only {Monday 5929.00 DARIEN BRONX GOODS} should only show for DARIEN BRONX GOODS
What I have so far.
select
Dim_Date.WeekDayName,
sum(dbo.DIM_PRODUCT.PRODUCT_PRICE) as [Total Profit],
DIM_D_STORE.STORE_NAME as [Store Name]
from
dbo.DIM_EMPLOYEE
inner join dbo.S_ORDER_FACT on
dbo.DIM_EMPLOYEE.EMPLOYEE_ID = dbo.S_ORDER_FACT.ORDER_EMPLOYEEID
inner join dbo.DIM_CUSTOMER on
dbo.DIM_CUSTOMER.CUSTOMERID = dbo.S_ORDER_FACT.ORDER_CUSTOMERID
inner join dbo.Dim_Date on
dbo.Dim_Date.DateKey = dbo.S_ORDER_FACT.ORDER_DATEID
inner join dbo.DIM_D_STORE on
dbo.DIM_D_STORE.STOREID = dbo.S_ORDER_FACT.ORDER_STOREID
inner join dbo.DIM_PRODUCT on
dbo.DIM_PRODUCT.PRODUCTID = dbo.S_ORDER_FACT.ORDER_PRODUCTID
group by
DIM_D_STORE.STORE_NAME,
Dim_Date.WeekDayName
order by
DIM_D_STORE.STORE_NAME,
[Total Profit] desc
offset 0 rows ;
[Output in image ]
here is one way using window functions:
select * from (
select
Dim_Date.WeekDayName,
sum(dbo.DIM_PRODUCT.PRODUCT_PRICE) as [Total Profit],
DIM_D_STORE.STORE_NAME as [Store Name],
rank() over (partition by STORE_NAME order by sum(dbo.DIM_PRODUCT.PRODUCT_PRICE) desc) rn
from
dbo.DIM_EMPLOYEE
inner join dbo.S_ORDER_FACT on
dbo.DIM_EMPLOYEE.EMPLOYEE_ID = dbo.S_ORDER_FACT.ORDER_EMPLOYEEID
inner join dbo.DIM_CUSTOMER on
dbo.DIM_CUSTOMER.CUSTOMERID = dbo.S_ORDER_FACT.ORDER_CUSTOMERID
inner join dbo.Dim_Date on
dbo.Dim_Date.DateKey = dbo.S_ORDER_FACT.ORDER_DATEID
inner join dbo.DIM_D_STORE on
dbo.DIM_D_STORE.STOREID = dbo.S_ORDER_FACT.ORDER_STOREID
inner join dbo.DIM_PRODUCT on
dbo.DIM_PRODUCT.PRODUCTID = dbo.S_ORDER_FACT.ORDER_PRODUCTID
group by
DIM_D_STORE.STORE_NAME,
Dim_Date.WeekDayName
) table where rn = 1
Wouldn't Top 1 do the job for selecting highest profit?
select Top 1,
Dim_Date.WeekDayName,
sum(dbo.DIM_PRODUCT.PRODUCT_PRICE) as [Total Profit],
DIM_D_STORE.STORE_NAME as [Store Name]
from
dbo.DIM_EMPLOYEE
inner join dbo.S_ORDER_FACT on
dbo.DIM_EMPLOYEE.EMPLOYEE_ID = dbo.S_ORDER_FACT.ORDER_EMPLOYEEID
inner join dbo.DIM_CUSTOMER on
dbo.DIM_CUSTOMER.CUSTOMERID = dbo.S_ORDER_FACT.ORDER_CUSTOMERID
inner join dbo.Dim_Date on
dbo.Dim_Date.DateKey = dbo.S_ORDER_FACT.ORDER_DATEID
inner join dbo.DIM_D_STORE on
dbo.DIM_D_STORE.STOREID = dbo.S_ORDER_FACT.ORDER_STOREID
inner join dbo.DIM_PRODUCT on
dbo.DIM_PRODUCT.PRODUCTID = dbo.S_ORDER_FACT.ORDER_PRODUCTID
group by
DIM_D_STORE.STORE_NAME,
Dim_Date.WeekDayName
order by
[Total Profit] desc,
DIM_D_STORE.STORE_NAME

Query to get the min date for the duplicate records

Below is my query, if there duplicate records I need to filter based on dates.
select
X.[po number],
(X.[ grn number]),
(X.[grn docentry]),
(X.ItemCode),
(X.[grn total]),
(X.tax),
(x.DocDate)[docdate]
from (
SELECT Distinct
T0.[DocNum] [po number],
T3.[DocNum] [ grn number],
T3.DocEntry [grn docentry],
T1.ItemCOde,
(T3.DocDate),
CASE WHEN T3.DocCur != 'SGD'
then (T4.PriceBefDi * T4.Quantity)
ELSE T4.LineTotal
END [grn total],
CASE WHEN T3.DocCur != 'SGD'
THEN T4.VatSumFrgn
ELSE T4.VatSum
END as [tax]
FROM OPOR T0
INNER JOIN POR1 T1 ON T0.DocEntry = T1.DocEntry
INNER JOIN PDN1 T4 on T1.DocEntry = T4.BaseEntry and T1.LineNum = T4.BaseLine
INNER JOIN OPDN T3 on T3.DocEntry = T4.DocEntry
)X
where X.[po number] in (37199, 37431, 37163, 37163, 37548)
and X.[grn total] in (1350.0000, 650.0000, 140.0000, 372.0000, 685.0000)
Below is my result set. if there are similar item codes, amount, tax amount. I need get only one record based on the minimum date for those matching. The highlighted red color must not show in the result set.
The actual output is like below:
You need to aggregate and select - what looks like - the min of each group:
select X.[po number], Min(X.[grn number])[grn number], Min(X.[grn docentry])[grn docentry], X.ItemCode, X.[grn total], X.tax, Min(X.DocDate) [docdate] from (
select distinct T0.[DocNum] [po number], T3.[DocNum] [ grn number], T3.DocEntry [grn docentry], T1.ItemCOde, T3.DocDate,
case when T3.DocCur != 'SGD' then (T4.PriceBefDi * T4.Quantity) else T4.LineTotal end [grn total] ,
case when T3.DocCur != 'SGD' then T4.VatSumFrgn else T4.VatSum end as [tax]
from OPOR T0
inner join POR1 T1 on T0.DocEntry = T1.DocEntry
inner join PDN1 T4 on T1.DocEntry = T4.BaseEntry and T1.LineNum = T4.BaseLine
inner join OPDN T3 on T3.DocEntry = T4.DocEntry
)X
where X.[po number] in (37199, 37431, 37163, 37163, 37548) and X.[grn total] in (1350.0000, 650.0000, 140.0000, 372.0000, 685.0000)
group by X.[po number], X.ItemCode, X.[grn total], X.tax
Use GROUP BY for and set HAVING clause MIN(x.DocDate).
I guess that your unique column is x.ItemCode and add the rest of column.
Sample:
GROUP BY x.ItemCode
HAVING MIN(x.DocDate)
One way is
select top(1) with ties *
from (
-- your original query
) t
order by row_number() over(partition by ItemCode, [grn total], tax order by docdate)

using sql subtotals

I have the following select statement:
SELECT
c.compname AS [Company]
,x.Ressnavn AS [Client]
,a.jobid AS [Job Number]
,a.JobNavn AS [Job Name]
,t.TName [Task Name]
,cu.DayDate AS [Booking Date]
,cu.HrsBooked AS [Scheduled Hours]
,tr.Sale AS [Sales Value]
,(cu.HrsBooked) * (tr.Sale) AS [Total]
FROM job a
INNER JOIN jobplan jp on jp.JobId=a.jobid
INNER JOIN JobDimensions AS z ON z.jobid = a.jobid
INNER JOIN Ress AS x ON x.RessId = z.custid
INNER JOIN JobPrice AS y ON y.JobId = a.Jobid
INNER JOIN task t on t.PlanId = jp.PlanId
INNER JOIN JobPriceactivity AS w ON w.priceId = y.priceId
INNER JOIN taskres tr ON tr.TaskId = t.TaskId
INNER JOIN emp e ON e.EmpId = tr.ResId
INNER JOIN comp c ON e.compid = c.compid
INNER JOIN CapUsed AS cu ON cu.RefId = tr.TaskResId AND cu.RefType=1
INNER JOIN arpaccount AS ar ON e.empname = ar.arpaccname
AND CAST (cu.DayDate AS DATE) BETWEEN #startdate AND #enddate
WHERE c.compid = '107' AND e.EMPID >='2' AND cu.HrsBooked > '0'
GROUP BY
x.Ressnavn
,a.jobid
,a.JobNavn
,t.TName
,cu.DayDate
,cu.HrsBooked
,y.priceid
,tr.Sale
,c.compname
That gives me the following output but I would like to add in a subtotal of the column 'Total' at each change in client.
An example of what I would like to try and get to is highlighted in green on the output screen grab.
Can anyone advise on the best way to do this?
Try using GROUP BY ROLLUP:
SELECT
x.Ressnavn AS [Client],
c.compname AS [Company],
a.jobid AS [Job Number],
a.JobNavn AS [Job Name],
t.TName [Task Name],
cu.DayDate AS [Booking Date],
cu.HrsBooked AS [Scheduled Hours],
tr.Sale AS [Sales Value],
(cu.HrsBooked) * (tr.Sale) AS [Total]
FROM (...)
GROUP BY
x.Ressnavn,
ROLLUP (
c.compname,
a.jobid,
a.JobNavn,
t.TName,
cu.DayDate,
cu.HrsBooked,
y.priceid,
tr.Sale )

SQL: How do I show all Items in Inventory and Sum sales of items sold in a time period?

I am trying to find all items on hand from #Supplier_ID and summarize any sales since #Begin_Date. What is returned are all items on hand that have never been sold and those sold since #Begin_Date. Items on hand that were sold before #Begin_Date are excluded from the results. How do I fix that?
I am using SQL Server 2012 and SSRS v3.
SELECT DISTINCT
inventory_supplier.supplier_id AS [Supp ID],
address.name AS Supplier,
inv_loc.location_id AS [Inventory Loc ID],
inv_mast.item_id AS [Item ID],
inv_mast.item_desc AS [Item Desc],
inv_loc.qty_on_hand AS QOH,
inv_loc.moving_average_cost AS MAC,
invoice_line.qty_shipped,
invoice_hdr.customer_id AS [Customer ID],
invoice_hdr.bill2_name AS Customer,
oe_line.source_loc_id AS [Sales Source Loc]
FROM
inventory_supplier
INNER JOIN
inv_mast ON inventory_supplier.inv_mast_uid = inv_mast.inv_mast_uid
INNER JOIN
address ON inventory_supplier.supplier_id = address.id
FULL OUTER JOIN
invoice_line ON inv_mast.inv_mast_uid = invoice_line.inv_mast_uid
FULL OUTER JOIN
inv_loc ON inv_mast.inv_mast_uid = inv_loc.inv_mast_uid
FULL OUTER JOIN
invoice_hdr ON invoice_line.invoice_no = invoice_hdr.invoice_no
FULL OUTER JOIN
oe_line ON invoice_hdr.order_no = oe_line.order_no
AND invoice_line.inv_mast_uid = oe_line.inv_mast_uid
WHERE
(inventory_supplier.supplier_id = #Supplier_ID)
AND (invoice_hdr.invoice_date >= #Begin_Date
OR invoice_hdr.invoice_date IS NULL)
AND (inv_loc.qty_on_hand > 0)
ORDER BY
[Item ID], [Inventory Loc ID], [Customer ID], [Sales Source Loc]
You could move your invoice_hdr.invoice_date >= #Begin_Date to your join statement
FULL OUTER JOIN
invoice_hdr ON invoice_line.invoice_no = invoice_hdr.invoice_no
AND invoice_hdr.invoice_date >= #Begin_Date
Don't see a lot of FULL OUTER JOINs. Sure you don't want LEFT JOIN here?
You might want to separate out the Invoice information from the Inventory information into a subquery, and LEFT JOIN to the Invoice information.
SELECT DISTINCT
inventory_supplier.supplier_id AS [Supp ID],
address.name AS Supplier,
inv_loc.location_id AS [Inventory Loc ID],
inv_mast.item_id AS [Item ID],
inv_mast.item_desc AS [Item Desc],
inv_loc.qty_on_hand AS QOH,
inv_loc.moving_average_cost AS MAC,
invoices.qty_shipped,
invoices.customer_id AS [Customer ID],
invoices.bill2_name AS Customer,
invoices.source_loc_id AS [Sales Source Loc]
FROM
inventory_supplier
INNER JOIN
inv_mast ON inventory_supplier.inv_mast_uid = inv_mast.inv_mast_uid
INNER JOIN
address ON inventory_supplier.supplier_id = address.id
INNER JOIN
inv_loc ON inv_mast.inv_mast_uid = inv_loc.inv_mast_uid
LEFT OUTER JOIN
(SELECT
invoice_line.inv_mast_uid,
invoice_line.qty_shipped,
invoice_hdr.customer_id,
invoice_hdr.bill2_name,
oe_line.source_loc_id
FROM
invoice_line
INNER JOIN
invoice_hdr ON invoice_line.invoice_no = invoice_hdr.invoice_no
INNER JOIN
oe_line ON invoice_hdr.order_no = oe_line.order_no
AND invoice_line.inv_mast_uid = oe_line.inv_mast_uid
WHERE
invoice_hdr.invoice_date >= #Begin_Date
) invoices ON invoices.inv_mast_uid = inv_mast.inv_mast_uid
WHERE
inventory_supplier.supplier_id = #Supplier_ID
AND inv_loc.qty_on_hand > 0
ORDER BY
[Item ID], [Inventory Loc ID], [Customer ID], [Sales Source Loc]
Try changing
WHERE
(inventory_supplier.supplier_id = #Supplier_ID)
AND (invoice_hdr.invoice_date >= #Begin_Date
OR invoice_hdr.invoice_date IS NULL)
AND (inv_loc.qty_on_hand > 0)
to
WHERE
(inventory_supplier.supplier_id = #Supplier_ID)
AND (invoice_hdr.invoice_date >= #Begin_Date)
AND (inv_loc.qty_on_hand > 0)
The problem is because you are including dates, invoice_hdr.invoice_date that are NULL in the WHERE clause. Simply remove it:
WHERE
(inventory_supplier.supplier_id = #Supplier_ID)
AND (invoice_hdr.invoice_date >= #Begin_Date)
AND (inv_loc.qty_on_hand > 0)

SQL - query to report MAX DATE results or NULL results

I have an SQL database with 3 tables:
Customer record table, holding master data (each row is unique)
Customer notes, each note data/time stamped (there could be many notes per customer, or none at all)
Product table, showing which customer has bought which product
Table: tbl_Customer_Records
CustomerID---- Company Name-----Company Segment----- Promo Code
Table: tbl_Customer_Notes
CustomerID---- Note-----Created Date
Table: tbl_Customer_Products
CustomerID---- Product Category
What I want is to pull a list of customer records which includes the latest note only, so there are no duplicate lines if multiple notes exist. But I also want my report to include customer records if no notes exist at all. I've achieved the first part of this with a SELECT MAX function, and that works well, the problem is when I add the OR = NULL clause in the final line of code below. This doesn't work, and I can't figure out a solution.
Any suggestions will be greatly appreciated!
SELECT
[tbl_Customer_Records].[CustomerID],
[tbl_Customer_Records].[Company Name],
[tbl_Customer_Records].[Company Segment],
[tbl_Customer_Records].[Promo Code],
[tbl_Customer_Notes].[Note],
[tbl_Customer_Products].[Product Category]
FROM
tbl_Customer_Records
LEFT OUTER JOIN tbl_Customer_Notes
ON tbl_Customer_Records.CustomerID = tbl_Customer_Notes.CustomerID
LEFT OUTER JOIN tbl_Customer_Products
ON tbl_Customer_Records.CustomerID = tbl_Customer_Products.CustomerID
WHERE
[Product Category] in ('Nuts','Bolts','Screws','Spanners')
AND
[Created Date] in (SELECT MAX ([Created Date]) FROM tbl.Customer_Notes GROUP BY [CustomerID])
OR tbl_Customer_Note.Note is null
There're a few tricks to do this kind of query (row_number or join with grouped data), but I think most cleanest one in your case is to use outer apply:
select
cr.[CustomerID],
cr.[Company Name],
cr.[Company Segment],
cr.[Promo Code],
cn.[Note],
cp.[Product Category]
from tbl_Customer_Records as cr
left outer join tbl_Customer_Products as cp on cp.CustomerID = cr.CustomerID
outer apply (
select top 1
t.[Note]
from tbl_Customer_Notes as t
where t.[CustomerID] = cr.[CustomerID]
order by t.[Created_Date] desc
) as cn
where
cp.[Product Category] in ('Nuts','Bolts','Screws','Spanners')
Changed all clumsy table name.column name to alias.column name, I think it's much more readable this way.
Or:
select
cr.[CustomerID],
cr.[Company Name],
cr.[Company Segment],
cr.[Promo Code],
cn.[Note],
cp.[Product Category]
from tbl_Customer_Records as cr
left outer join tbl_Customer_Products as cp on cp.CustomerID = cr.CustomerID
left outer join tbl_Customer_Notes as cn on
cn.CustomerID = cr.CustomerID and
cn.[Created_Date] = (select max(t.[Created_Date]) from tbl_Customer_Notes as t where t.CustomerID = cr.CustomerID)
where
cp.[Product Category] in ('Nuts','Bolts','Screws','Spanners')
You can add your filter condition in ON predicate to preserve rows from left table and fetch only required matching rows from right table, from first LEFT OUTER JOIN operator. Following query should work:
SELECT
CR.[CustomerID],
CR.[Company_Name],
CR.[Company_Segment],
CR.[Promo_Code],
CN.[Note],
CP.[Product_Category]
FROM
tbl_Customer_Records CR
LEFT OUTER JOIN tbl_Customer_Notes CN
ON CR.CustomerID = CN.CustomerID AND CN.[Created_Date] in (SELECT MAX ([Created_Date])
FROM tbl_Customer_Notes
WHERE CR.CustomerID = tbl_Customer_Notes.CustomerID
GROUP BY [CustomerID])
LEFT OUTER JOIN tbl_Customer_Products CP
ON CR.CustomerID = CP.CustomerID
WHERE
[Product_Category] in ('Nuts','Bolts','Screws','Spanners')
Should work, tried with NULL values:
SELECT a.[CustomerID],
a.[Company Name],
a.[Company Segment],
a.[Promo Code],
a.[Note],
a.[Product Category]
FROM (
SELECT
cr.[CustomerID],
cr.[Company Name],
cr.[Company Segment],
cr.[Promo Code],
cn.[Note],
cp.[Product Category],
ROW_NUMBER() OVER(PARTITION BY cr.[CustomerID] ORDER BY cn.[Created Date] DESC) as rnk
FROM tbl_Customer_Records cr
LEFT JOIN tbl_Customer_Notes cn
ON cr.CustomerID = cn.CustomerID
LEFT JOIN tbl_Customer_Products cp
ON cr.CustomerID = cp.CustomerID
WHERE cp.[Product Category] in ('Nuts','Bolts','Screws','Spanners') )a
WHERE a.rnk = 1
try to use CustomerID not in (select CustomerID from tbl_Customer_Note)