SQL Server - how to sum field from multiple table - sql-server

I have 3 tables like this
I want to sum SewingPrice from WorkDetail table and CombinationPrice from Details table based on WorkDate in WorkHeader table. I'm using this query and it fails (returns 1700 for CombinationPrice and 80400 for SewingPrice). I want to return 1700 for CombinationPrice and 20400 for SewingPrice.
select
SUM(det.CombinationPrice) CombinationPrice,
SUM(wd.SewingPrice) SewingPrice
from
Details det
join
WorkDetail wd on det.WorkDetailId = wd.WorkDetailId
join
WorkHeader wh on wd.WorkHeaderId = wh.WorkHeaderId
where
wh.DateStart = '2013-12-20'

SELECT * FROM WorkHeader WH
INNER JOIN (SELECT SUM(SewingPrice) SumSew, WorkHeaderID
FROM WorkDetail
GROUP BY WorkHeaderID) Sew ON
WH.WorkHeaderID = Sew.WorkHeaderID
INNER JOIN (SELECT SUM(Det.CombinationPrice) SumCombo, WD.WorkHeaderID
FROM Details Det
INNER JOIN WorkDetail WD on WD.WorkDetailID = Det.WorkDetailID
GROUP BY WorkHeaderID) Combo ON
Combo.WorkHeaderID = WH.WorkHeaderID
WHERE WH.WorkDate = '2013-12-20'

As I mentioned in my comment, you have to use group by
select
wd.workHeaderID,
SUM(det.CombinationPrice) CombinationPrice,
SUM(wd.SewingPrice) SewingPrice
from
WorkHeader wh
left join
workdetail wd on wd.WorkHeaderId = wh.WorkHeaderId
left join
(select det.workdetailid ,SUM(det.CombinationPrice)combinationprice from details det group by det.workdetailid)as det on det.WorkDetailId = wd.WorkDetailId
where
wh.workdate = '20131220'
group by wd.workheaderid

Related

How convert this consult in LinQ

I'm trying to convert in this query
from lckr in BD.Inventory_Lockers join emp in BD.Employees on lckr.EmployeeID equals emp.EmployeeID
join jti in BD.JobTitles on emp.JobTitleID equals jti.JobTitleID
join dpt in BD.JobTitles on jti.DepartmentID equals dpt.DepartmentID
select new { DepartmentN = dpt.Department.DepartmentName, asignationDate= lckr.asignation_date, lockers = lckr.LockersID.Count() }
.ToList())
I understand that you want to convert to T-SQL, it would be as follows
SELECT
dpt.DepartmentName AS DepartmentN
,lckr.asignation_date AS asignationDate
,COUNT(lckr.LockersID) AS lockers
FROM Inventory_Lockers lckr
JOIN Employees emp ON emp.EmployeeID = lckr.EmployeeID
JOIN JobTitles jti ON jti.JobTitleID = emp.JobTitleID
JOIN Department dpt ON jti.DepartmentID = dpt.DepartmentID
GROUP BY
dpt.DepartmentName
,lckr.asignation_date

I get wrong result when calculating weight

I have this query
SELECT ProjInfo.ProjectN AS BS,
ProjShipp.Parts,
SUM(CASE
WHEN DailyPaProd.FK_idNextProcess = 13
AND ProjInfo.FK_Status != 'VENDRE DES MATIERES PREMIERES' THEN ProjShipp.[Weight] * DailyPaProd.[Quantity]
ELSE 0
END) AS [weight fab],
SUM(ProjShipp.[Weight] * ProjShipp.ShippingNavisionQty) AS [weight Shipp]
FROM ProjectShipping ProjShipp
INNER JOIN ProjectInfo ProjInfo ON ProjInfo.id = ProjShipp.IdProject
INNER JOIN DailyPaintProduction DailyPaProd ON DailyPaProd.FK_idPartShip = ProjShipp.id
WHERE ProjInfo.ProjectN = 'BS-00799'
GROUP BY ProjInfo.ProjectN,
ProjShipp.Parts,
ProjShipp.[Weight];
when I run it I get this result
All result are correct except for TA1 on weight Shipp column I'm supposed to get 2352 instead of 11760.Why i am getting this error ,and how to fix it
Thanks in advance.
Update
ProjectShipping table
ProjectInfo table
DailyPaintProduction table
This query worked for me
SELECT ProjInfo.ProjectN AS BS,
ProjShipp.Parts,
(Select SUM(ProjectShipping.[Weight]*DailyPaintProduction.[Quantity])
from DailyPaintProduction
Inner Join ProjectShipping on ProjectShipping.id=DailyPaintProduction.FK_idPartShip
Inner Join ProjectInfo on ProjectInfo.id=ProjectShipping.IdProject
Where DailyPaintProduction.FK_idPartShip=ProjShipp.id and
FK_idNextProcess=13 and
ProjectInfo.FK_Status!='VENDRE DES MATIERES PREMIERES')AS 'weight fab',
SUM(ProjShipp.[Weight]*ShippingNavisionQty)AS 'weight Shipp'
From ProjectShipping ProjShipp
Inner Join ProjectInfo ProjInfo on ProjInfo.id=ProjShipp.IdProject
WHERE ProjInfo.ProjectN = 'BS-00799'
GROUP BY ProjInfo.ProjectN,
ProjShipp.Parts,
ProjShipp.[Weight],
ProjShipp.id

Make one-to-one relation between two tables that have one-to-many relation in SQL

I have these queries :
SELECT
dbo.Lines.Unit, dbo.Lines.LineNumber, dbo.Lines.DocumentNumber,
dbo.BaseMaterials.Name AS MaterialName,
dbo.MaterialDescriptions.Name AS MaterialDescription,
dbo.MaterialDescriptions.Description,
dbo.MaterialScopes.ScopeName, dbo.MaterialScopeObjectNames.ObjectName,
dbo.MaterialDescriptions.Size1, dbo.MaterialDescriptions.Size2,
dbo.MaterialDescriptions.ItemCode, dbo.Materials.Quantity,
dbo.Materials.Discipline, dbo.Materials.Id, dbo.Lines.Id AS LineId
FROM
dbo.Materials
INNER JOIN
dbo.Lines ON dbo.Materials.LineId = dbo.Lines.Id
INNER JOIN
dbo.BaseMaterials ON dbo.Lines.BaseMaterialId = dbo.BaseMaterials.Id
INNER JOIN
dbo.MaterialDescriptions ON dbo.Materials.MaterialDescriptionId = dbo.MaterialDescriptions.Id
INNER JOIN
dbo.MaterialScopes ON dbo.MaterialDescriptions.MaterialScopeId = dbo.MaterialScopes.Id
INNER JOIN
dbo.MaterialScopeObjectNames ON dbo.MaterialDescriptions.MaterialScopeObjectId = dbo.MaterialScopeObjectNames.Id
It returns 16000 records. I have another tables with joints name that has a relation with material table on lineId every material can have multi joints so my query when I add joints table is like this :
SELECT
dbo.Lines.Unit, dbo.Lines.LineNumber, dbo.Lines.DocumentNumber,
dbo.BaseMaterials.Name AS MaterialName,
dbo.MaterialDescriptions.Name AS MaterialDescription,
dbo.MaterialDescriptions.Description, dbo.MaterialScopes.ScopeName,
dbo.MaterialScopeObjectNames.ObjectName, dbo.MaterialDescriptions.Size1,
dbo.MaterialDescriptions.Size2, dbo.MaterialDescriptions.ItemCode,
dbo.Materials.Quantity, dbo.Materials.Discipline, dbo.Materials.Id,
dbo.Lines.Id AS LineId, dbo.Joints.TestPackageId
FROM
dbo.Materials
INNER JOIN
dbo.Lines ON dbo.Materials.LineId = dbo.Lines.Id
INNER JOIN
dbo.BaseMaterials ON dbo.Lines.BaseMaterialId = dbo.BaseMaterials.Id
INNER JOIN
dbo.MaterialDescriptions ON dbo.Materials.MaterialDescriptionId = dbo.MaterialDescriptions.Id
INNER JOIN
dbo.MaterialScopes ON dbo.MaterialDescriptions.MaterialScopeId = dbo.MaterialScopes.Id
INNER JOIN
dbo.MaterialScopeObjectNames ON dbo.MaterialDescriptions.MaterialScopeObjectId = dbo.MaterialScopeObjectNames.Id
INNER JOIN
dbo.Joints ON dbo.Materials.LineId = dbo.Joints.LineId
As you can see in the last line i make a join between joints and materials to access the testpackageid column in joints table .but my result returns 220000records .How can i change the join type i mean left or right to just returns 16000 records with its testpackageId
You can't using JOIN. However, you can using CROSS APPLY:
FROM . . .
dbo.MaterialScopeObjectNames
ON dbo.MaterialDescriptions.MaterialScopeObjectId = dbo.MaterialScopeObjectNames.Id CROSS APPLY
(SELECT TOP 1 j.*
FROM dbo.Joints j
WHERE dbo.Materials.LineId = j.LineId
) J
Normally, you would include an ORDER BY when using TOP so you have some control over the row being returned.
Also note that the use of table aliases makes the query easier to write and to read.
You can get it very easily with just a subquery. Leave your query as it is, and add a subquery to get that information from Joints.
SELECT dbo.Lines.Unit, dbo.Lines.LineNumber, dbo.Lines.DocumentNumber, dbo.BaseMaterials.Name AS MaterialName, dbo.MaterialDescriptions.Name AS MaterialDescription, dbo.MaterialDescriptions.Description,
dbo.MaterialScopes.ScopeName, dbo.MaterialScopeObjectNames.ObjectName, dbo.MaterialDescriptions.Size1, dbo.MaterialDescriptions.Size2, dbo.MaterialDescriptions.ItemCode, dbo.Materials.Quantity,
dbo.Materials.Discipline, dbo.Materials.Id, dbo.Lines.Id AS LineId,
(select top 1 dbo.Joints.TestPackageId from dbo.Joints where dbo.Joints.LineId = dbo.Materials.LineId)
FROM dbo.Materials INNER JOIN
dbo.Lines ON dbo.Materials.LineId = dbo.Lines.Id INNER JOIN
dbo.BaseMaterials ON dbo.Lines.BaseMaterialId = dbo.BaseMaterials.Id INNER JOIN
dbo.MaterialDescriptions ON dbo.Materials.MaterialDescriptionId = dbo.MaterialDescriptions.Id INNER JOIN
dbo.MaterialScopes ON dbo.MaterialDescriptions.MaterialScopeId = dbo.MaterialScopes.Id INNER JOIN
dbo.MaterialScopeObjectNames ON dbo.MaterialDescriptions.MaterialScopeObjectId = dbo.MaterialScopeObjectNames.Id

need max(id)for multiple rows but am receiving multiple max id's

I need to retrieve the latest loadid by location now with multiple joins.
for example ibiza's latest loadid is 692 and there are 2 records. The query below retrieves all of the loadid's for that location and not just the max. how can i achieve bringing back the latest records by location with the max(loadid) from the query below:
select
MAX(t.loadid) AS loadid,
a.process_id,
p.partitionkey,
-- t.partitionkey,
p.partdesc,
p.partname,
c.catname,
r.rule_name,
r.file_path,
a.execution_start_time,
a.execution_end_time,
a.records_processed
-- a.status,
-- a.last_updated_by as processed_by,
-- a.last_update_date
FROM
data t
INNER JOIN part p
ON t.partitionkey = p.partitionkey
INNER JOIN process a
ON t.loadid = a.process_id
INNER JOIN categ c
ON t.catkey = c.catkey
INNER JOIN balance r
ON t.RULE_ID = r.RULE_ID
WHERE
p.partname = 'ibiza'
GROUP BY
t.loadid,
a.process_id,
p.partitionkey,
t.partitionkey,
p.partdesc,
p.partname,
c.catname,
r.rule_name,
r.file_path,
a.execution_start_time,
a.execution_end_time,
a.records_processed;
You can use CTE :
;WITH MaxLoadId AS
(
select MAX(t.loadid) AS loadid, p.partitionkey, p.partdesc, p.partname
FROM data t
INNER JOIN part p ON t.partitionkey = p.partitionkey
WHERE p.partname = 'ibiza'
GROUP BY p.partitionkey, p.partdesc, p.partname
)
select
mli.loadid AS loadid,
a.process_id,
mli.partitionkey,
-- t.partitionkey,
mli.partdesc,
mli.partname,
c.catname,
r.rule_name,
r.file_path,
a.execution_start_time,
a.execution_end_time,
a.records_processed
-- a.status,
-- a.last_updated_by as processed_by,
-- a.last_update_date
FROM MaxLoadId mli
INNER JOIN data t ON mli.loadid = t.loadid
INNER JOIN process a ON mli.loadid = a.process_id
INNER JOIN categ c ON t.catkey = c.catkey
INNER JOIN balance r ON t.RULE_ID = r.RULE_ID

JOIN codition in SQL Server

After applying join condition on two tables I want records which is maximum among records of left table
My query
SELECT a1.*,
t.*,
( a1.trnratefrom - t.trnratefrom )AS minrate,
( a1.trnrateto - t.trnrateto ) AS maxrate
FROM (SELECT a.srno,
trndate,
b.trnsrno,
Upper(Rtrim(Ltrim(b.trnstate))) AS trnstate,
Upper(Rtrim(Ltrim(b.trnarea))) AS trnarea,
Upper(Rtrim(Ltrim(b.trnquality))) AS trnquality,
Upper(Rtrim(Ltrim(b.trnlength))) AS trnlength,
Upper(Rtrim(Ltrim(b.trnunit))) AS trnunit,
b.trnratefrom,
b.trnrateto,
a.remark,
entdate
FROM mstprodrates a
INNER JOIN trnprodrates b
ON a.srno = b.srno)a1
INNER JOIN (SELECT c.srno,
trndate,
d.trnsrno,
Upper(Rtrim(Ltrim(d.trnstate))) AS trnstate,
Upper(Rtrim(Ltrim(d.trnarea))) AS trnarea,
Upper(Rtrim(Ltrim(d.trnquality))) AS trnquality,
Upper(Rtrim(Ltrim(d.trnlength))) AS trnlength,
Upper(Rtrim(Ltrim(d.trnunit))) AS trnunit,
d.trnratefrom,
d.trnrateto,
c.remark,
entdate
FROM mstprodrates c
INNER JOIN trnprodrates d
ON c.srno = d.srno) AS t
ON a1.trnstate = t.trnstate
AND a1.trnquality = t.trnquality
AND a1.trnunit = t.trnunit
AND a1.trnlength = t.trnlength
AND a1.trnarea = t.trnarea
AND a1.remark = t.remark
WHERE t.srno = (SELECT MAX(srno)
FROM a1
WHERE srno < a1.srno)
If you mean to say,
you want Records exist in Left table but not in right then use LEFT OUTER JOIN.

Resources