Query to get values and sum of attributes - sql-server

I'm trying to write a query but getting an error for finding sum of weights and volume:
SQL Error [8120] [S0001]: Column 'Attribute.attribute_value' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
com.microsoft.sqlserver.jdbc.SQLServerException: Column 'Attribute.attribute_value' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
SELECT
dg.delivery_group_id,
ctr.container_type,
ven.attribute_value AS 'vendor',
carr.attribute_value AS 'carrier',
com.attribute_value AS 'commodity',
conv.attribute_value AS 'conveyance',
stor.attribute_value AS 'store',
SUM(ISNULL(CAST(wgt.attribute_value AS float), 0.0)) AS 'weight',
SUM(ISNULL(CAST(vol.attribute_value AS float), 0.0)) AS 'volume'
FROM (SELECT
pal.container_id AS 'container_id',
pal.container_type AS container_type,
cas.container_id AS 'sub_container_id',
pal.loc_id
FROM container pal
LEFT OUTER JOIN container cas
ON cas.parent_container_id = pal.container_id
AND cas.container_type = 'Case'
WHERE pal.container_type = 'Pallet') AS ctr
INNER JOIN Container_Detail cdtl
ON (ctr.container_id = cdtl.container_id
OR ctr.sub_container_id = cdtl.container_id)
INNER JOIN container_delivery cd
ON cdtl.detail_id = cd.detail_id
INNER JOIN delivery_line dl
ON cd.delivery_line_id = dl.delivery_line_id
INNER JOIN delivery_group dg
ON dl.delivery_group_id = dg.delivery_group_id
INNER JOIN Attribute ven
ON cdtl.attribute_id=ven.attribute_id AND ven.attribute_type='vendor'
INNER JOIN Attribute carr
ON cdtl.attribute_id=carr.attribute_id AND carr.attribute_type='carrier'
INNER JOIN Attribute com
ON cdtl.attribute_id=com.attribute_id AND com.attribute_type='commodity'
INNER JOIN Attribute conv
ON cdtl.attribute_id=conv.attribute_id AND
conv.attribute_type='conveyance'
INNER JOIN Attribute stor
ON cdtl.attribute_id=stor.attribute_id AND stor.attribute_type='store'
INNER JOIN Attribute wgt
ON cdtl.attribute_id=wgt.attribute_id AND wgt.attribute_type='weight'
INNER JOIN Attribute vol
ON cdtl.attribute_id=vol.attribute_id AND vol.attribute_type='volume'
WHERE ctr.container_id = '00007712120038613557'
OR ctr.sub_container_id = '00007712120038613557'
GROUP BY dg.delivery_group_id,
ctr.container_type,ctr.container_id,ctr.sub_container_id,
wgt.attribute_value, vol.attribute_value
Following is my table :

Add all of these to your group by:
group by dg.delivery_group_id,
ctr.container_type,
ven.attribute_value AS,
carr.attribute_value ,
com.attribute_value AS ,
conv.attribute_value ,
stor.attribute_value

SELECT
dg.delivery_group_id,
ctr.container_type,
ven.attribute_value AS 'vendor',
carr.attribute_value AS 'carrier',
com.attribute_value AS 'commodity',
conv.attribute_value AS 'conveyance',
stor.attribute_value AS 'store',
SUM(ISNULL(CAST(wgt.attribute_value AS float), 0.0)) AS 'weight',
SUM(ISNULL(CAST(vol.attribute_value AS float), 0.0)) AS 'volume'
FROM (SELECT pal.container_id AS 'container_id',
pal.container_type AS container_type, cas.container_id AS 'sub_container_id', pal.loc_id FROM container pal LEFT OUTER JOIN container cas ON cas.parent_container_id = pal.container_id
AND cas.container_type = 'Case' WHERE pal.container_type = 'Pallet') AS ctr INNER JOIN Container_Detail cdtl ON (ctr.container_id = cdtl.container_id OR ctr.sub_container_id = cdtl.container_id) INNER JOIN container_delivery cd
ON cdtl.detail_id = cd.detail_id INNER JOIN delivery_line dl ON cd.delivery_line_id = dl.delivery_line_id INNER JOIN delivery_group dg ON dl.delivery_group_id = dg.delivery_group_id INNER JOIN Attribute ven
ON cdtl.attribute_id=ven.attribute_id AND ven.attribute_type='vendor'
INNER JOIN Attribute carr
ON cdtl.attribute_id=carr.attribute_id AND carr.attribute_type='carrier'
INNER JOIN Attribute com
ON cdtl.attribute_id=com.attribute_id AND com.attribute_type='commodity'
INNER JOIN Attribute conv
ON cdtl.attribute_id=conv.attribute_id AND
conv.attribute_type='conveyance'
INNER JOIN Attribute stor
ON cdtl.attribute_id=stor.attribute_id AND stor.attribute_type='store'
INNER JOIN Attribute wgt
ON cdtl.attribute_id=wgt.attribute_id AND wgt.attribute_type='weight'
INNER JOIN Attribute vol
ON cdtl.attribute_id=vol.attribute_id AND vol.attribute_type='volume'
WHERE ctr.container_id = '00007712120038613557'
OR ctr.sub_container_id = '00007712120038613557'
group by
dg.delivery_group_id,
ctr.container_type,
ven.attribute_value AS,
carr.attribute_value ,
com.attribute_value AS ,
conv.attribute_value ,
stor.attribute_value

Related

Error shows "Incorrect Syntax near the keyword WHERE"

Here is my query:
SELECT
FO.Placement_date, FO.Delivery_date, FO.Order_Id, FO.Cid,
CPD.Name, FOD.Product, FOD.Type, FOD.Article_Quantity,
FOD.Quantity_In_Metre, FOD.Price_Per_Metre, FPD.Total,
Discount, FPD.OfferDiscount, FPD.ExtraCharges
FROM
F_Orders_Details FOD
INNER JOIN
F_PaymentDetails FPD
INNER JOIN
F_Orders FO ON FO.Order_Id = FOD.Order_Id
INNER JOIN
CustomerIds CPD ON CPD.Cid = FO.Cid
AND CPD.BranchId = FO.BranchId
WHERE
FO.Placement_Date BETWEEN '2017-10-01' AND '2017-10-31'
AND FO.branchid = '1'
ORDER BY
FO.Placement_Date
I did not find anything wrong.
You are missing a ON clause on the first inner join which relates FOD and FDP. I reformatted the code slightly so you can spot it more easily:
SELECT FO.Placement_date,
FO.Delivery_date,
FO.Order_Id,
FO.Cid,
CPD.Name,
FOD.Product,
FOD.Type,
FOD.Article_Quantity,
FOD.Quantity_In_Metre,
FOD.Price_Per_Metre,
FPD.Total,
FPD.Discount,
FPD.OfferDiscount,
FPD.ExtraCharges
FROM F_Orders_Details FOD
INNER JOIN F_PaymentDetails FPD /*On what?*/
INNER JOIN F_Orders FO
ON FO.Order_Id = FOD.Order_Id
INNER JOIN CustomerIds CPD
ON CPD.Cid = FO.Cid
AND CPD.BranchId = FO.BranchId
WHERE FO.Placement_Date BETWEEN '2017-10-01' AND '2017-10-31'
AND FO.branchid = '1'
ORDER BY FO.Placement_Date

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

groupby in view of sql returns aggregate error

I am trying to create a view with this query as you can see here:
SELECT dbo.Lines.LineNumber, dbo.Lines.DocumentNumber, dbo.Joints.JointNumber, dbo.Joints.JointSize, dbo.Joints.ShopField, dbo.Joints.WPS, dbo.WeldDetails.StateStep2 AS WeldState, dbo.Welds.WeldNumber,
dbo.FitUps.FitUpNumber, MAX(dbo.WeldDetails.Id) AS WeldDetailId, MAX(dbo.FitUpDetails.Id) AS FitupDetailId, dbo.Joints.Id AS JointId, dbo.Ends.Name, dbo.Joints.THK, dbo.FitUpDetails.StateStep2 AS FitupState,
dbo.Joints.Revision, dbo.Joints.Note
FROM dbo.FitUps INNER JOIN
dbo.Welds INNER JOIN
dbo.Joints INNER JOIN
dbo.WeldDetails ON dbo.Joints.Id = dbo.WeldDetails.JointId INNER JOIN
dbo.FitUpDetails ON dbo.Joints.Id = dbo.FitUpDetails.JointId ON dbo.Welds.Id = dbo.WeldDetails.WeldId ON dbo.FitUps.Id = dbo.FitUpDetails.FitUpId INNER JOIN
dbo.Lines ON dbo.Joints.LineId = dbo.Lines.Id INNER JOIN
dbo.Ends ON dbo.Joints.EndId = dbo.Ends.Id
GROUP BY dbo.Joints.Id
But when i want to save the view i get this error :
Here is a part of my data :
Every joint id can have multi fitupdetailid and welddetailid in my view i want just show the maximum value of fitupdetailid and welddetailid of my joint.
I rewrote your query with a more readable join structure than what your GUI spit out. This should run for you and fix your error. Whether the results are what you want or not depends on your data. You may also want to re-order the grouping to group how you want, hierarchically. But all of those columns will need to be in the grouping in one form or another.
SELECT
dbo.Lines.LineNumber,
dbo.Lines.DocumentNumber,
dbo.Joints.JointNumber,
dbo.Joints.JointSize,
dbo.Joints.ShopField,
dbo.Joints.WPS,
dbo.WeldDetails.StateStep2 AS WeldState,
dbo.Welds.WeldNumber,
dbo.FitUps.FitUpNumber,
MAX(dbo.WeldDetails.Id) AS WeldDetailId,
MAX(dbo.FitUpDetails.Id) AS FitupDetailId,
dbo.Joints.Id AS JointId,
dbo.Ends.Name,
dbo.Joints.THK,
dbo.FitUpDetails.StateStep2 AS FitupState,
dbo.Joints.Revision,
dbo.Joints.Note
FROM
dbo.FitUps
INNER JOIN dbo.FitUpDetails ON dbo.FitUps.Id = dbo.FitUpDetails.FitUpId
INNER JOIN dbo.Joints ON dbo.Joints.Id = dbo.FitUpDetails.JointId
INNER JOIN dbo.WeldDetails ON dbo.Joints.Id = dbo.WeldDetails.JointId
INNER JOIN dbo.Welds ON dbo.Welds.Id = dbo.WeldDetails.WeldId
INNER JOIN dbo.Lines ON dbo.Joints.LineId = dbo.Lines.Id
INNER JOIN dbo.Ends ON dbo.Joints.EndId = dbo.Ends.Id
GROUP BY
dbo.Lines.LineNumber,
dbo.Lines.DocumentNumber,
dbo.Joints.JointNumber,
dbo.Joints.JointSize,
dbo.Joints.ShopField,
dbo.Joints.WPS,
dbo.WeldDetails.StateStep2,
dbo.Welds.WeldNumber,
dbo.FitUps.FitUpNumber,
dbo.Joints.Id,
dbo.Ends.Name,
dbo.Joints.THK,
dbo.FitUpDetails.StateStep2,
dbo.Joints.Revision,
dbo.Joints.Note

Use groupby with inner join to get unique record on single column

I need unique record on colum a.[id] so I am using group but it getting error
Msg 8120, Level 16, State 1, Line 3
Column 'dbo.assessment_dfn.name' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Query
SELECT a.[id] AS AssessmentID
--,ad.[code] AS Assessment_Dfn_Code
,ad.[name] AS Assessment_Dfn_name
,mdfn.[id] AS Module_Dfn_ID
,a.[student_stage]
,a.[assessments_sitting]
,a.[sitting_date]
,ads.[sitting_number]
,s.[id] AS StudentID
,a.[assessor] AS AssessorID
,mdfn.[lead] AS ModuleLead
,a.[submission_date]
,a.[status]
,a.[complete]
,a.[assessment]
,a.[saved]
,ele_cliPro.[grade] AS GradeID
,codGrd.[name] AS GradeName
FROM [adb_TestDb].[dbo].[assessments] AS a (NOLOCK)
INNER JOIN [adb_TestDb].[dbo].[student_stage] AS ss ON a.[student_stage] = ss.[id]
INNER JOIN [dbo].[assessment_dfn_sittings] ads WITH (NOLOCK) ON ads.[id] = a.[assessments_sitting]
INNER JOIN [adb_TestDb].[dbo].[students] AS s ON ss.student = s.[id]
INNER JOIN [dbo].[assessment_dfn] ad WITH (NOLOCK) ON ad.[id] = ads.[assessment]
INNER JOIN [dbo].[module_dfn] AS mdfn ON ad.[module] = mdfn.[id]
INNER JOIN [adb_TestDb].[dbo].[elements_clinicalprocedures] AS ele_cliPro ON a.[id] = ele_cliPro.[assessment]
INNER JOIN [adb_TestDb].[dbo].[codes_grade_details] AS codGrd ON ele_cliPro.[grade] = codGrd.[id] AND codGrd.[id] = 4
where a.id= 2532
group by a.[id]
As suggested by SQL you cannot get columns when using GROUP BY if they are not in that clause or in an aggregate function.
If you need only one record and you know all values are the same you could try to use an aggregate function for all the values required (eg MAX) but this solution should be used only if you are completely aware of getting only one among the possible values!

SQL Server - how to sum field from multiple table

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

Resources