This question already has answers here:
Reason for Column is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause [duplicate]
(4 answers)
Closed 4 years ago.
I have a query like this:
SELECT DISTINCT
dbo.T_Order_Header.F_Exhibitor,
dbo.T_Order_Header.F_Exhibition,
dbo.T_Exhibition.F_Exhibition_Name,
dbo.T_Exhibitor.F_Exhibitor_Name,
dbo.T_Order_Detail.F_ItemCode,
dbo.T_L2Category.F_L2Cat_Name,
SUM(dbo.T_Order_Detail.F_Qty-dbo.T_Order_Detail.F_CNQty) AS F_Qty,
dbo.T_L1Category.F_L1Cat_Name,
dbo.T_Order_Header.F_Stand,
dbo.T_Category.F_Cat_name,
dbo.T_ExStand.F_Bld_Code,
dbo.T_ExBuilding.F_Bld_name
FROM dbo.T_Order_Header
LEFT OUTER JOIN dbo.T_OrderAttachment
ON dbo.T_OrderAttachment.F_OrderNumber = dbo.T_Order_Header.F_OrderNumber
LEFT OUTER JOIN dbo.T_Order_Detail
ON dbo.T_Order_Detail.[Header_ID] = dbo.T_Order_Header.[ID]
LEFT OUTER JOIN dbo.T_L2Category
ON dbo.T_Order_Detail.F_ItemCode = dbo.T_L2Category.F_ItemCode
LEFT OUTER JOIN dbo.T_L1Category
ON dbo.T_L1Category.F_L1Cat_Code = dbo.T_L2Category.F_L1Cat_Code
LEFT OUTER JOIN dbo.T_Category
ON dbo.T_Category.F_Cat_Code = dbo.T_L2Category.F_Cat_Code
LEFT OUTER JOIN dbo.T_ExStand
ON dbo.T_ExStand.F_Stand_Code = dbo.T_Order_Header.F_Stand
LEFT OUTER JOIN dbo.T_ExBuilding
ON dbo.T_ExStand.F_Bld_Code = dbo.T_ExBuilding.F_Bld_Code
LEFT OUTER JOIN dbo.T_Exhibition
ON dbo.T_Order_Header.F_Exhibition = dbo.T_Exhibition.F_Exhibition_Code
LEFT OUTER JOIN dbo.T_Exhibitor
ON dbo.T_Order_Header.F_Exhibitor = dbo.T_Exhibitor.F_Exhibitor_Code
WHERE
F_Stand IN(
SELECT F_Stand_Code
FROM T_ExStand
WHERE
F_Site_Code ='DWTC'
AND F_Bld_Code = 'HALL1-4 & CONCOURSE'
)
AND T_Order_Header.F_Exhibition = '12004'
AND T_Order_Header.F_IsActive = 1
AND F_Exhibitor='2467'
I want to show sum of F_qty but I keep getting this error:
Column 'dbo.T_Order_Header.F_Exhibitor' is invalid in the select list
because it is not contained in either an aggregate function or the
GROUP BY clause
You need to group by with all the columns which you're selecting (other than the one which is in the aggregate function), something like below query:
SELECT
dbo.T_Order_Header.F_Exhibitor,
dbo.T_Order_Header.F_Exhibition,
dbo.T_Exhibition.F_Exhibition_Name,
dbo.T_Exhibitor.F_Exhibitor_Name,
dbo.T_Order_Detail.F_ItemCode,
dbo.T_L2Category.F_L2Cat_Name,
SUM(dbo.T_Order_Detail.F_Qty-dbo.T_Order_Detail.F_CNQty) AS F_Qty,
dbo.T_L1Category.F_L1Cat_Name,
dbo.T_Order_Header.F_Stand,
dbo.T_Category.F_Cat_name,
dbo.T_ExStand.F_Bld_Code,
dbo.T_ExBuilding.F_Bld_name
FROM dbo.T_Order_Header
LEFT OUTER JOIN dbo.T_OrderAttachment
ON dbo.T_OrderAttachment.F_OrderNumber = dbo.T_Order_Header.F_OrderNumber
LEFT OUTER JOIN dbo.T_Order_Detail
ON dbo.T_Order_Detail.[Header_ID] = dbo.T_Order_Header.[ID]
LEFT OUTER JOIN dbo.T_L2Category
ON dbo.T_Order_Detail.F_ItemCode = dbo.T_L2Category.F_ItemCode
LEFT OUTER JOIN dbo.T_L1Category
ON dbo.T_L1Category.F_L1Cat_Code = dbo.T_L2Category.F_L1Cat_Code
LEFT OUTER JOIN dbo.T_Category
ON dbo.T_Category.F_Cat_Code = dbo.T_L2Category.F_Cat_Code
LEFT OUTER JOIN dbo.T_ExStand
ON dbo.T_ExStand.F_Stand_Code = dbo.T_Order_Header.F_Stand
LEFT OUTER JOIN dbo.T_ExBuilding
ON dbo.T_ExStand.F_Bld_Code = dbo.T_ExBuilding.F_Bld_Code
LEFT OUTER JOIN dbo.T_Exhibition
ON dbo.T_Order_Header.F_Exhibition = dbo.T_Exhibition.F_Exhibition_Code
LEFT OUTER JOIN dbo.T_Exhibitor
ON dbo.T_Order_Header.F_Exhibitor = dbo.T_Exhibitor.F_Exhibitor_Code
WHERE
F_Stand IN(
SELECT F_Stand_Code
FROM T_ExStand
WHERE
F_Site_Code ='DWTC'
AND F_Bld_Code = 'HALL1-4 & CONCOURSE'
)
AND T_Order_Header.F_Exhibition = '12004'
AND T_Order_Header.F_IsActive = 1
AND F_Exhibitor='2467'
group by dbo.T_Order_Header.F_Exhibitor,
dbo.T_Order_Header.F_Exhibition,
dbo.T_Exhibition.F_Exhibition_Name,
dbo.T_Exhibitor.F_Exhibitor_Name,
dbo.T_Order_Detail.F_ItemCode,
dbo.T_L2Category.F_L2Cat_Name,
dbo.T_L1Category.F_L1Cat_Name,
dbo.T_Order_Header.F_Stand,
dbo.T_Category.F_Cat_name,
dbo.T_ExStand.F_Bld_Code,
dbo.T_ExBuilding.F_Bld_name
Use below query for your requirement.
SELECT DISTINCT
dbo.T_Order_Header.F_Exhibitor,
dbo.T_Order_Header.F_Exhibition,
dbo.T_Exhibition.F_Exhibition_Name,
dbo.T_Exhibitor.F_Exhibitor_Name,
dbo.T_Order.F_ItemCode,
dbo.T_L2Category.F_L2Cat_Name,
T_Order.F_Qty F_Qty,
dbo.T_L1Category.F_L1Cat_Name,
dbo.T_Order_Header.F_Stand,
dbo.T_Category.F_Cat_name,
dbo.T_ExStand.F_Bld_Code,
dbo.T_ExBuilding.F_Bld_name
FROM dbo.T_Order_Header
LEFT OUTER JOIN dbo.T_OrderAttachment
ON dbo.T_OrderAttachment.F_OrderNumber = dbo.T_Order_Header.F_OrderNumber
LEFT OUTER JOIN
(select SUM(dbo.T_Order_Detail.F_Qty)-sum(dbo.T_Order_Detail.F_CNQty) AS F_Qty,
[Header_ID],F_ItemCode from
dbo.T_Order_Detail
group by
[Header_ID]) T_Order ON dbo.T_Order.[Header_ID] = dbo.T_Order_Header.[ID]
LEFT OUTER JOIN dbo.T_L2Category
ON dbo.F_ItemCode.F_ItemCode = dbo.T_L2Category.F_ItemCode
LEFT OUTER JOIN dbo.T_L1Category
ON dbo.T_L1Category.F_L1Cat_Code = dbo.T_L2Category.F_L1Cat_Code
LEFT OUTER JOIN dbo.T_Category
ON dbo.T_Category.F_Cat_Code = dbo.T_L2Category.F_Cat_Code
LEFT OUTER JOIN dbo.T_ExStand
ON dbo.T_ExStand.F_Stand_Code = dbo.T_Order_Header.F_Stand
LEFT OUTER JOIN dbo.T_ExBuilding
ON dbo.T_ExStand.F_Bld_Code = dbo.T_ExBuilding.F_Bld_Code
LEFT OUTER JOIN dbo.T_Exhibition
ON dbo.T_Order_Header.F_Exhibition = dbo.T_Exhibition.F_Exhibition_Code
LEFT OUTER JOIN dbo.T_Exhibitor
ON dbo.T_Order_Header.F_Exhibitor = dbo.T_Exhibitor.F_Exhibitor_Code
WHERE
F_Stand IN(
SELECT F_Stand_Code
FROM T_ExStand
WHERE
F_Site_Code ='DWTC'
AND F_Bld_Code = 'HALL1-4 & CONCOURSE'
)
AND T_Order_Header.F_Exhibition = '12004'
AND T_Order_Header.F_IsActive = 1
AND F_Exhibitor='2467'
You are using SQL group function. In this case you have to add GROUP BY clause at the end of the sql-statement. Please add all generic columns to GROUP BY clause except F_Qty. And remove DISTINCT from your select statement.
Related
I am writing an equivalent logic in BQ as in my source system. In source SQL server side it is working fine. But in Big query it is failing with the OR condition in the last left outer join condition. If I am moving the OR condition in the where clause it is giving wrong count. Need help to fix this issue. How can I re write the below query ?
SELECT count(*)
FROM stprof PRO
INNER JOIN stdim DIM
ON (DIM.diSet = PRO.diSet)
INNER JOIN DQConfig CFG
ON (CFG.ConSet = PRO.ConSet)
LEFT OUTER JOIN AgSt CCT
ON (CCT.StSet = PRO.StSet)
INNER JOIN stprof SummPRO
ON (SummPRO.diSet = DIM.SummdiSet AND
SummPRO.dIntervalStart = PRO.dIntervalStart AND
SummPRO.SiteId = PRO.SiteId AND
SummPRO.nDuration = PRO.nDuration)
LEFT OUTER JOIN AgSt SummCCT
ON (SummCCT.StSet = SummPRO.StSet)
LEFT OUTER JOIN AgentStatus SummSTS
ON (
SummSTS.StSet = SummPRO.StSet
OR
SummSTS.StSet = PRO.StSet)
WHERE DIM.cType = 'A'
You can replace LEFT JOIN with CROSS JOIN and move condition from ON clause to WHERE clause as in below example
#standardSQL
SELECT COUNT(*)
FROM stprof PRO
INNER JOIN stdim DIM
ON DIM.diSet = PRO.diSet
INNER JOIN DQConfig CFG
ON CFG.ConSet = PRO.ConSet
LEFT OUTER JOIN AgSt CCT
ON CCT.StSet = PRO.StSet
INNER JOIN stprof SummPRO
ON SummPRO.diSet = DIM.SummdiSet
AND SummPRO.dIntervalStart = PRO.dIntervalStart
AND SummPRO.SiteId = PRO.SiteId
AND SummPRO.nDuration = PRO.nDuration
LEFT OUTER JOIN AgSt SummCCT
ON SummCCT.StSet = SummPRO.StSet
CROSS JOIN AgentStatus SummSTS
WHERE DIM.cType = 'A'
AND (
SummSTS.StSet = SummPRO.StSet
OR SummSTS.StSet = PRO.StSet
)
When i run this query in window system behave correctly UNNSET
but when i run this query Linux behave different.unnset duplicate record list on different row
SELECT DISTINCT
"billing_billmanagement"."creation_date",
"billing_billmanagement"."bill_number",
unnest(array_agg(DISTINCT "inventory_product"."product_name")) AS "product",
unnest(array_agg(DISTINCT "services_service"."name")) AS "service"
FROM "billing_billmanagement"
INNER JOIN "users_staffuser" ON ("billing_billmanagement"."staff_id" = "users_staffuser"."id")
INNER JOIN "auth_user" ON ("users_staffuser"."user_id" = "auth_user"."id")
LEFT OUTER JOIN "billing_customerproductbill" ON ("billing_billmanagement"."id" = "billing_customerproductbill"."bill_id")
LEFT OUTER JOIN "inventory_product" ON ("billing_customerproductbill"."product_id" = "inventory_product"."id")
LEFT OUTER JOIN "billing_customerservicebill" ON ("billing_billmanagement"."id" = "billing_customerservicebill"."bill_id")
LEFT OUTER JOIN "services_service" ON ("billing_customerservicebill"."service_id" = "services_service"."id")
WHERE "billing_billmanagement"."creation_date" BETWEEN '2017-12-04' AND '2017-12-06'
GROUP BY billing_billmanagement.creation_date,
billing_billmanagement.bill_number
ORDER BY "billing_billmanagement"."creation_date" ASC
If getting duplicate rows is the problem, try this
SELECT billing_billmanagement.creation_date,
billing_billmanagement.bill_number,
inventory_product.product_name AS product,
services_service.name AS service
FROM billing_billmanagement
INNER JOIN users_staffuser ON (billing_billmanagement.staff_id = users_staffuser.id)
INNER JOIN auth_user ON (users_staffuser.user_id = auth_user.id)
LEFT OUTER JOIN billing_customerproductbill ON (billing_billmanagement.id = billing_customerproductbill.bill_id)
LEFT OUTER JOIN inventory_product ON (billing_customerproductbill.product_id = inventory_product.id)
LEFT OUTER JOIN billing_customerservicebill ON (billing_billmanagement.id = billing_customerservicebill.bill_id)
LEFT OUTER JOIN services_service ON (billing_customerservicebill.service_id = services_service.id)
WHERE billing_billmanagement.creation_date BETWEEN '2017-12-04' AND '2017-12-06'
GROUP BY 1,
2,
3,
4
ORDER BY 1 ASC;
When i run this query in window system behave correctly UNNSET
but when i run this query Linux behave different.unnset duplicate record list on different row
SELECT DISTINCT
"billing_billmanagement"."creation_date",
"billing_billmanagement"."bill_number",
unnest(array_agg(DISTINCT "inventory_product"."product_name")) AS "product",
unnest(array_agg(DISTINCT "services_service"."name")) AS "service"
FROM "billing_billmanagement"
INNER JOIN "users_staffuser" ON ("billing_billmanagement"."staff_id" = "users_staffuser"."id")
INNER JOIN "auth_user" ON ("users_staffuser"."user_id" = "auth_user"."id")
LEFT OUTER JOIN "billing_customerproductbill" ON ("billing_billmanagement"."id" = "billing_customerproductbill"."bill_id")
LEFT OUTER JOIN "inventory_product" ON ("billing_customerproductbill"."product_id" = "inventory_product"."id")
LEFT OUTER JOIN "billing_customerservicebill" ON ("billing_billmanagement"."id" = "billing_customerservicebill"."bill_id")
LEFT OUTER JOIN "services_service" ON ("billing_customerservicebill"."service_id" = "services_service"."id")
WHERE "billing_billmanagement"."creation_date" BETWEEN '2017-12-04' AND '2017-12-06'
GROUP BY billing_billmanagement.creation_date,
billing_billmanagement.bill_number
ORDER BY "billing_billmanagement"."creation_date" ASC
If getting duplicate rows is the problem, try this
SELECT billing_billmanagement.creation_date,
billing_billmanagement.bill_number,
inventory_product.product_name AS product,
services_service.name AS service
FROM billing_billmanagement
INNER JOIN users_staffuser ON (billing_billmanagement.staff_id = users_staffuser.id)
INNER JOIN auth_user ON (users_staffuser.user_id = auth_user.id)
LEFT OUTER JOIN billing_customerproductbill ON (billing_billmanagement.id = billing_customerproductbill.bill_id)
LEFT OUTER JOIN inventory_product ON (billing_customerproductbill.product_id = inventory_product.id)
LEFT OUTER JOIN billing_customerservicebill ON (billing_billmanagement.id = billing_customerservicebill.bill_id)
LEFT OUTER JOIN services_service ON (billing_customerservicebill.service_id = services_service.id)
WHERE billing_billmanagement.creation_date BETWEEN '2017-12-04' AND '2017-12-06'
GROUP BY 1,
2,
3,
4
ORDER BY 1 ASC;
Is it possible to do case statements and to left outer joins like I am doing below? I put comments on what I am trying to achieve.
SELECT
eventGame.Id,
eventGame.[Type] AS GameType
FROM GrassrootsHoops.EventGame eventGame
LEFT OUTER JOIN (SELECT
divisionGameTeamResult.Id,
divisionGameTeamResult.GameId,
COALESCE(divisionPool.Name, divisionTeamPoolPoolBracket.Name) AS DivisionPoolName
FROM GrassrootsHoops.DivisionGameTeamResult divisionGameTeamResult
LEFT OUTER JOIN
-- CASE eventGame.[Type] = 1 THEN
GrassrootsHoops.DivisionTeamPoolGame divisionTeamPoolGame
ON divisionTeamPoolGame.Id = divisionGameTeamResult.Id
LEFT OUTER JOIN GrassrootsHoopS.DivisionTeamPool divisionTeamPool
ON divisionTeamPool.Id = divisionTeamPoolGame.DivisionTeamPoolId
LEFT OUTER JOIN GrassrootsHoops.DivisionPool divisionPool
ON divisionPool.Id = divisionTeamPool.DivisionPoolId
LEFT OUTER JOIN GrassrootsHoops.DivisionPoolSettings divisionPoolSettings
ON divisionPool.Id = divisionPoolSettings.Id
LEFT OUTER JOIN GrassrootsHoops.DivisionTeam divisionTeam
ON divisionTeam.Id = divisionTeamPool.DivisionTeamId
LEFT OUTER JOIN GrassrootsHoops.Team team
ON team.Id = divisionTeam.Id
LEFT OUTER JOIN
-- CASE eventGame.[Type] = 2 THEN
GrassrootsHoops.DivisionBracketParticipant divisionBracketGameParticipant
ON divisionBracketGameParticipant.DivisionGameTeamResultId = divisionGameTeamResult.Id
LEFT OUTER JOIN GrassrootsHoops.DivisionBracketParticipantPart divisionBracketParticipantPart
ON divisionBracketParticipantPart.Id = divisionBracketGameParticipant.DivisionBracketParticipantPartId
LEFT OUTER JOIN GrassrootsHoops.DivisionBracketParticipantTeam divisionBracketGameParticipantTeam
ON divisionBracketGameParticipantTeam.Id = divisionBracketGameParticipant.Id
LEFT OUTER JOIN GrassrootsHoops.DivisionTeam divisionTeamBracket
ON divisionTeamBracket.Id = divisionBracketGameParticipantTeam.DivisionTeamId
LEFT OUTER JOIN GrassrootsHoops.Team teamBracket
ON teamBracket.Id = divisionTeamBracket.Id
LEFT OUTER JOIN GrassrootsHoops.DivisionBracketParticipantBracket divisionBracketParticipantBracket
ON divisionBracketParticipantBracket.Id = divisionBracketGameParticipant.Id
LEFT OUTER JOIN GrassrootsHoops.DivisionBracket divisionBracketParticipantBracketBracket
ON divisionBracketParticipantBracketBracket.Id = divisionBracketParticipantBracket.DivisionBracketId
LEFT OUTER JOIN GrassrootsHoops.DivisionBracketParticipantPool divisionBracketGameParticipantPool
ON divisionBracketGameParticipantPool.Id = divisionBracketGameParticipant.Id
LEFT OUTER JOIN GrassrootsHoops.DivisionPool divisionPoolBracket
ON divisionPoolBracket.Id = divisionBracketGameParticipantPool.DivisionPoolId
LEFT OUTER JOIN GrassrootsHoops.DivisionBracketParticipantTeamPool divisionBracketGameParticipantTeamPool
ON divisionBracketGameParticipantTeamPool.Id = divisionBracketGameParticipant.Id
LEFT OUTER JOIN GrassrootsHoops.DivisionTeamPool divisionTeamPoolBracket
ON divisionTeamPoolBracket.Id = divisionBracketGameParticipantTeamPool.DivisionTeamPoolId
LEFT OUTER JOIN GrassrootsHoops.DivisionPool divisionTeamPoolPoolBracket
ON divisionTeamPoolPoolBracket.Id = divisionTeamPoolBracket.DivisionPoolId
LEFT OUTER JOIN GrassrootsHoops.DivisionTeam divisionTeamPoolTeamBracket
ON divisionTeamPoolTeamBracket.Id = divisionTeamPoolBracket.DivisionTeamId
LEFT OUTER JOIN GrassrootsHoops.Team teamPoolTeamBracket
ON teamPoolTeamBracket.Id = divisionTeamPoolTeamBracket.Id
WHERE divisionGameTeamResult.HomeTeam = 1) homeTeam
ON homeTeam.GameId = eventGame.GameId
You can't do case statements with outer joins. I think you can do what you want, though by using a UNION. Here's an example using a simpler schema where we are doing two separate joins based on the type of game.
SELECT
Game.Id,
PoolResult.Score
FROM
Game
JOIN PoolResult
ON PoolResult.GameId = Game.Id
WHERE
Game.GameType = 1
UNION
SELECT
Game.Id,
BracketResult.Score
FROM
Game
JOIN BracketResult
ON BracketResult.GameId = Game.Id
WHERE
Game.GameType = 2
(Here's a working version at SQL Fiddle)
For your query, you just want to write two completely separate queries one for each type of game. Once you have that working for each separate query, just stick a UNION in between them and the results will be concatenated together. Here's your query modified to use a UNION. I don't have an easy way to check it for errors, so there's probably some minor errors
SELECT
divisionGameTeamResult.Id,
eventGame.[Type] AS GameType
FROM
GrassrootsHoops.EventGame eventGame
JOIN GrassrootsHoops.DivisionGameTeamResult divisionGameTeamResult
ON (divisionGameTeamResult.GameId = eventGame.GameId
JOIN GrassrootsHoops.DivisionTeamPoolGame divisionTeamPoolGame
ON divisionTeamPoolGame.Id = divisionGameTeamResult.Id
JOIN GrassrootsHoopS.DivisionTeamPool divisionTeamPool
ON divisionTeamPool.Id = divisionTeamPoolGame.DivisionTeamPoolId
JOIN GrassrootsHoops.DivisionPool divisionPool
ON divisionPool.Id = divisionTeamPool.DivisionPoolId
JOIN GrassrootsHoops.DivisionPoolSettings divisionPoolSettings
ON divisionPool.Id = divisionPoolSettings.Id
JOIN GrassrootsHoops.DivisionTeam divisionTeam
ON divisionTeam.Id = divisionTeamPool.DivisionTeamId
JOIN GrassrootsHoops.Team team
ON team.Id = divisionTeam.Id
WHERE
divisionGameTeamResult.HomeTeam = 1
AND
eventGame.[Type] = 1
UNION
SELECT
divisionGameTeamResult.Id,
eventGame.[Type] AS GameType
FROM
GrassrootsHoops.EventGame eventGame
JOIN GrassrootsHoops.DivisionGameTeamResult divisionGameTeamResult
ON (divisionGameTeamResult.GameId = eventGame.GameId)
JOIN GrassrootsHoops.DivisionBracketParticipant divisionBracketGameParticipant
ON divisionBracketGameParticipant.DivisionGameTeamResultId = divisionGameTeamResult.Id
JOIN GrassrootsHoops.DivisionBracketParticipantPart divisionBracketParticipantPart
ON divisionBracketParticipantPart.Id = divisionBracketGameParticipant.DivisionBracketParticipantPartId
JOIN GrassrootsHoops.DivisionBracketParticipantTeam divisionBracketGameParticipantTeam
ON divisionBracketGameParticipantTeam.Id = divisionBracketGameParticipant.Id
JOIN GrassrootsHoops.DivisionTeam divisionTeamBracket
ON divisionTeamBracket.Id = divisionBracketGameParticipantTeam.DivisionTeamId
JOIN GrassrootsHoops.Team teamBracket
ON teamBracket.Id = divisionTeamBracket.Id
JOIN GrassrootsHoops.DivisionBracketParticipantBracket divisionBracketParticipantBracket
ON divisionBracketParticipantBracket.Id = divisionBracketGameParticipant.Id
JOIN GrassrootsHoops.DivisionBracket divisionBracketParticipantBracketBracket
ON divisionBracketParticipantBracketBracket.Id = divisionBracketParticipantBracket.DivisionBracketId
JOIN GrassrootsHoops.DivisionBracketParticipantPool divisionBracketGameParticipantPool
ON divisionBracketGameParticipantPool.Id = divisionBracketGameParticipant.Id
JOIN GrassrootsHoops.DivisionPool divisionPoolBracket
ON divisionPoolBracket.Id = divisionBracketGameParticipantPool.DivisionPoolId
JOIN GrassrootsHoops.DivisionBracketParticipantTeamPool divisionBracketGameParticipantTeamPool
ON divisionBracketGameParticipantTeamPool.Id = divisionBracketGameParticipant.Id
JOIN GrassrootsHoops.DivisionTeamPool divisionTeamPoolBracket
ON divisionTeamPoolBracket.Id = divisionBracketGameParticipantTeamPool.DivisionTeamPoolId
JOIN GrassrootsHoops.DivisionPool divisionTeamPoolPoolBracket
ON divisionTeamPoolPoolBracket.Id = divisionTeamPoolBracket.DivisionPoolId
JOIN GrassrootsHoops.DivisionTeam divisionTeamPoolTeamBracket
ON divisionTeamPoolTeamBracket.Id = divisionTeamPoolBracket.DivisionTeamId
JOIN GrassrootsHoops.Team teamPoolTeamBracket
ON teamPoolTeamBracket.Id = divisionTeamPoolTeamBracket.Id
WHERE
divisionGameTeamResult.HomeTeam = 1
AND
eventGame.[Type] = 1
I am a SQL Server beginner and so I have been using MS Access to create queries and then have been amending them for SQL Server.
I have created a query which includes a left join, which works perfectly in Access but when I copy the SQL code across to SQL Server it does not show the null values and I cannot work out why.
I want to show all of the attribute values whether they include a value or not. Can anyone help? The code is as follows:
SELECT DISTINCT
tbLease.LeaseTitle
, tbAttributeValue.AttributeTemplateDefinitionLinkID
, tbAttributeValue.Value
FROM
((((tbBusinessUnit
LEFT JOIN
tbAttributeValue ON tbBusinessUnit.BusinessUnitID = tbAttributeValue.ParentID)
INNER JOIN
tbBuildingLinkBusinessUnit ON tbBusinessUnit.BusinessUnitID = tbBuildingLinkBusinessUnit.BusinessUnitID)
INNER JOIN
tbBuilding ON tbBuildingLinkBusinessUnit.BuildingID = tbBuilding.BuildingID)
INNER JOIN
(tbUnitLocation
INNER JOIN
tbUnit ON tbUnitLocation.UnitID = tbUnit.UnitID)
ON tbBuilding.BuildingID = tbUnitLocation.LocationID)
INNER JOIN
tbLease ON tbUnit.UnitID = tbLease.UnitID
WHERE
(((tbAttributeValue.AttributeTemplateDefinitionLinkID) = 30
Or (tbAttributeValue.AttributeTemplateDefinitionLinkID) = 31
Or (tbAttributeValue.AttributeTemplateDefinitionLinkID) = 32));
Hard to say what you want without some examples but you might want this:
WHERE coalesce(tbAttributeValue.AttributeTemplateDefinitionLinkID,30) in (30,31,32);
This will give you items where AttributeTemplateDefinitionLinkID is null
(that is it did not join on the left join) OR is one of those 3 values.
Right now if you don't join with the left join it will not display that row because of the where condition, so your left join is the same as an inner join.
The NULL values you would normally see with a left join are getting filtered out by your WHERE clause.
Any time you add filters to a WHERE clause that apply to an outer joined table, it will effectively make it the same as an inner join unless you include NULL values as an option in your where clause as well.
SELECT DISTINCT
tbLease.LeaseTitle,
tbAttributeValue.AttributeTemplateDefinitionLinkID,
tbAttributeValue.Value
FROM
tbBusinessUnit
LEFT JOIN tbAttributeValue ON tbBusinessUnit.BusinessUnitID = tbAttributeValue.ParentID
INNER JOIN tbBuildingLinkBusinessUnit ON tbBusinessUnit.BusinessUnitID = tbBuildingLinkBusinessUnit.BusinessUnitID
INNER JOIN tbBuilding ON tbBuildingLinkBusinessUnit.BuildingID = tbBuilding.BuildingID
INNER JOIN tbUnitLocation ON tbBuilding.BuildingID = tbUnitLocation.LocationID
INNER JOIN tbUnit ON tbUnitLocation.UnitID = tbUnit.UnitID
INNER JOIN tbLease ON tbUnit.UnitID = tbLease.UnitID
WHERE
tbAttributeValue.AttributeTemplateDefinitionLinkID in (30, 31, 32)
or tbAttributeValue.AttributeTemplateDefinitionLinkID is null
Move the right table filters from where clause to ON condition when you are using Left Outer Join else Left join will be implicitly converted to INNER JOIN. Try this
SELECT DISTINCT tblease.leasetitle,
tbattributevalue.attributetemplatedefinitionlinkid,
tbattributevalue.value
FROM tbbusinessunit
LEFT JOIN tbattributevalue
ON tbbusinessunit.businessunitid = tbattributevalue.parentid
AND ( tbattributevalue.attributetemplatedefinitionlinkid IN
( 30, 31, 32 )
OR tbattributevalue.attributetemplatedefinitionlinkid IS
NULL )
INNER JOIN tbbuildinglinkbusinessunit
ON tbbusinessunit.businessunitid =
tbbuildinglinkbusinessunit.businessunitid
INNER JOIN tbbuilding
ON tbbuildinglinkbusinessunit.buildingid = tbbuilding.buildingid
INNER JOIN tbunitlocation
ON tbbuilding.buildingid = tbunitlocation.locationid
INNER JOIN tbunit
ON tbunitlocation.unitid = tbunit.unitid
INNER JOIN tblease
ON tbunit.unitid = tblease.unitid