using sql subtotals - sql

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 )

Related

Multiplying 2 columns in sql but calculation is incorrect?

I have the following select statement:
SELECT c.compname AS [Company]
,e.empname AS [Employee Name]
,a.jobid AS [Job Number]
,a.JobNavn AS [Job Name]
,t.TName [Task Name]
,cu.DayDate AS [Booking Date]
,cu.HrsBooked AS [Scheduled Hours]
,x.Ressnavn AS [Client]
,tr.Sale
,SUM(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 e.EMPID >= '2'
AND cu.HrsBooked > '0'
GROUP BY c.compname
,e.empname
,a.jobid
,a.JobNavn
,t.TName
,cu.DayDate
,cu.HrsBooked
,x.Ressnavn
,y.priceid
,tr.Sale
But the calculation of my 'SUM' in the select is not correct as highlighted in yellow in the following extract
I was expecting something like the below highlighted in green:
Can anyone highlight where I am going wrong either in my main code or column sum?

SQL - How to select data row with Maximum value within a specific column? [Part 2]

This is a continuation from my earlier question.
Planning to create view with multiple join statements. And I have each separate components ready to assemble:
select A.[Course Code], A.[Course Title],A.Result, A.[Employee No], A.[Employee Name], A.Section,
max(B.ActStartDate) as [Last Training Date], B.ValidTo as [Validity Period], A.[Status], A.Flag as [Record Flag]
from
(select c.CourseID, c.[CourseCode] as [Course Code], c.[CourseTitle] as [Course Title],
c.[CourseCode] + ' - ' + c.[CourseTitle] as [Result],
b.[EMPLOYEE_NO] as [Employee No], b.[EMPLOYEE_NAME] as [Employee Name],
b.[SECTION_CODE] + ' - ' + b.[SECTION_DESCRIPTION] as [Section], b.[EMPLOYEE_STATUS] as [Status], a.Flag
from [SQLDB3].[dbo].[ZOJT_EMP_COURSE] a inner join
[SQLDB3].[dbo].[vEMPLOYEE_PROFILE] b on a.Employee_No = b.EMPLOYEE_NO inner join
[SQLDB3].[dbo].[tTMS_Course] c on c.CourseCode = a.CourseCode) as A
inner join
(select a.SchID as [SchID], b.CourseID as [CourseID], a.EmpNo as [EmpNo],
b.ActStartDate as [ActStartDate], a.ValidTo as [ValidTo]
from [SQLDB3].[dbo].[tTMS_Training_Record] a
inner join
(select z.schid, z.CourseID as [CourseID],max(z.ActStartDate) as [ActStartDate]
from [SQLDB3].[dbo].[tTMS_Training_Schedule] z group by z.SchID, z.CourseID)as b
on a.SchID = b.SchID )as B on A.[Employee No]= B.EmpNo
group by A.CourseID, A.[Course Code], A.[Course Title],A.Result, A.[Employee No], A.[Employee Name], A.Section,
B.ValidTo, A.[Status], A.Flag
Each Course Code and Employee No combination should only have 1 row of entry in the table with the Max value of Last Training Date.
Although the components works fine separately, when combined I get multiple records of the same Course Code and Employee No with different Last Training Date.
I'm honestly at a stump here. Any help?
use row_number window function
with cte as
( select A.[Course Code],
A.[Course Title],
A.Result,
A.[Employee No],
A.[Employee Name], A.Section,
B.ActStartDate as [Last Training Date],
B.ValidTo as [Validity Period],
A.[Status], A.Flag as [Record Flag]
,row_number() over(partition by A.[Course Code], A.[Employee No] order by B.ActStartDate desc) rn
from
(select c.CourseID, c.[CourseCode] as [Course Code], c.[CourseTitle] as [Course Title],
c.[CourseCode] + ' - ' + c.[CourseTitle] as [Result],
b.[EMPLOYEE_NO] as [Employee No], b.[EMPLOYEE_NAME] as [Employee Name],
b.[SECTION_CODE] + ' - ' + b.[SECTION_DESCRIPTION] as [Section], b.[EMPLOYEE_STATUS] as [Status], a.Flag
from [SQLDB3].[dbo].[ZOJT_EMP_COURSE] a inner join
[SQLDB3].[dbo].[vEMPLOYEE_PROFILE] b on a.Employee_No = b.EMPLOYEE_NO inner join
[SQLDB3].[dbo].[tTMS_Course] c on c.CourseCode = a.CourseCode) as A
inner join
(select a.SchID as [SchID], b.CourseID as [CourseID], a.EmpNo as [EmpNo],
b.ActStartDate as [ActStartDate], a.ValidTo as [ValidTo]
from [SQLDB3].[dbo].[tTMS_Training_Record] a
inner join
(select z.schid, z.CourseID as [CourseID],max(z.ActStartDate) as [ActStartDate]
from [SQLDB3].[dbo].[tTMS_Training_Schedule] z group by z.SchID, z.CourseID)as b
on a.SchID = b.SchID )as B on A.[Employee No]= B.EmpNo
) select * from cte where rn=1

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 select statement that checks two columns and returns the value from a third [duplicate]

This question already has answers here:
SQL Server Error:"SQL Server Subquery returned more than 1 value"
(2 answers)
Closed 7 years ago.
I am writing a query that accesses multiple tables in the same database. For one of the columns in the select statement, I need to return
Table1.Column4
where Table1.Column = Table3.Column1 AND
Table1.Column2 = Table4.Column1
I have it written as:
SELECT AccNum.FieldValue
FROM PersonFieldValuesVW
INNER JOIN PersonFieldValuesVW AccNum
ON AccNum.PersonId = InPerson.PersonId
INNER JOIN InPerson
ON InPerson.IncidentId = Incident.Id
WHERE AccNum.FieldDescr like '%Account Number%') as [Account Number],
This is returning the error:
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
Here is the full query, any assistance would be appreciated.
SELECT DISTINCT
CaseNum as [Case Number],
ALCategoryVW.Category as [Category],
ALCategoryVW.SubCategory as [Sub Category],
InAssign.AssignToName as [Assigned To],
ReportedDate as [Open Date],
EndDate as [Closed Date], --This a placeholder for a closed date
[Status],
SiteLoc1.Descr as [Loss Location],
LocDetails as [Loss Cost Center],
SiteLoc1.Region as [Region],
SiteLoc1.SubRegion as [Sub Region],
-- SiteLoc2.Descr as [Location Description], **Need this though returning all for the location?
CASE WHEN SAR.FieldId = '604NU' and SAR.FieldValue <> 'False' THEN 'YES' ELSE 'NO' END as [SAR Required],
Summary as [Incident Summary],
Disposition as [Case Disposition],
(
SELECT AccNum.FieldValue
FROM PersonFieldValuesVW
INNER JOIN PersonFieldValuesVW AccNum ON AccNum.PersonId = InPerson.PersonId
INNER JOIN InPerson ON InPerson.IncidentId = Incident.Id
WHERE AccNum.FieldDescr like '%Account Number%'
) as [Account Number],
FORMAT(AuditItemDetail.ItemValue, '#,###') as [Potential Loss],
FORMAT(AuditItemDetail.ItemValue - AuditItemDetail.PreventedExposureAmount, '#,###') as [Actual Loss]
FROM Incident
INNER JOIN ALCategoryVW ON ALCategoryVW.IncidentId = Incident.Id
INNER JOIN InAssign ON InAssign.IncidentId = Incident.Id
INNER JOIN SiteLoc1 ON SiteLoc1.Id = Incident.LocId
INNER JOIN SiteLoc2 ON SiteLoc2.SiteLoc1Id = SiteLoc1.Id
INNER JOIN IncidentFieldValuesVW SAR ON SAR.IncidentId = Incident.Id
INNER JOIN InItem ON InItem.IncidentId = Incident.Id
INNER JOIN AuditItemDetail ON AuditItemDetail.ItemId = InItem.ItemId
INNER JOIN InPerson ON InPerson.IncidentId = Incident.Id
INNER JOIN PersonFieldValuesVW AccNum ON AccNum.PersonId = InPerson.PersonId
This should resolve your error, but I'm not sure it is logically correct. If you have two records being returned in the sub-select, which one is the "right" one.
SELECT DISTINCT
CaseNum as [Case Number],
ALCategoryVW.Category as [Category],
ALCategoryVW.SubCategory as [Sub Category],
InAssign.AssignToName as [Assigned To],
ReportedDate as [Open Date],
EndDate as [Closed Date], --This a placeholder for a closed date
[Status],
SiteLoc1.Descr as [Loss Location],
LocDetails as [Loss Cost Center],
SiteLoc1.Region as [Region],
SiteLoc1.SubRegion as [Sub Region],
-- SiteLoc2.Descr as [Location Description], **Need this though returning all for the location?
CASE WHEN SAR.FieldId = '604NU' and SAR.FieldValue <> 'False' THEN 'YES' ELSE 'NO' END as [SAR Required],
Summary as [Incident Summary],
Disposition as [Case Disposition],
AccNum.FieldValue,
FORMAT(AuditItemDetail.ItemValue, '#,###') as [Potential Loss],
FORMAT(AuditItemDetail.ItemValue - AuditItemDetail.PreventedExposureAmount, '#,###') as [Actual Loss]
FROM Incident
INNER JOIN ALCategoryVW ON ALCategoryVW.IncidentId = Incident.Id
INNER JOIN InAssign ON InAssign.IncidentId = Incident.Id
INNER JOIN SiteLoc1 ON SiteLoc1.Id = Incident.LocId
INNER JOIN SiteLoc2 ON SiteLoc2.SiteLoc1Id = SiteLoc1.Id
INNER JOIN IncidentFieldValuesVW SAR ON SAR.IncidentId = Incident.Id
INNER JOIN InItem ON InItem.IncidentId = Incident.Id
INNER JOIN AuditItemDetail ON AuditItemDetail.ItemId = InItem.ItemId
INNER JOIN InPerson ON InPerson.IncidentId = Incident.Id
LEFT JOIN PersonFieldValuesVW AccNum ON AccNum.PersonId = InPerson.PersonId AND AccNum.FieldDescr like '%Account Number%'
***Updated based on comment.

SQL Query Second sum column squaring results

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