LEFT JOINS in MS Access - sql

I am trying to troubleshoot someone else's MS Access query and keep getting an invalid operation error. The Help doesn't seem to apply as I am just running a query. It all works as INNER JOINS but when I switch back to the LEFT JOIN the error.
SELECT *
FROM ((((orders
INNER JOIN orders_customers ON orders.CUST_ORDER_ID = orders_customers.ID)
LEFT JOIN quoted_theory ON orders.PART_ID = quoted_theory.PART_ID)
LEFT JOIN conversions ON orders.PART_ID = conversions.PART_ID)
LEFT JOIN dbo_WO_Header ON orders.CUST_ORDER_ID = dbo_WO_Header.PPC_Number)
INNER JOIN lines_qry ON orders.CUST_ORDER_ID = lines_qry.WORKORDER_BASE_ID
I can get one level of LEFT JOIN, but each time I add a second LEFT JOIN the error pops up.

Access' db engine frequently balks when mixing INNER and LEFT joins. If that query works without the last inner join ...
SELECT *
FROM
(((orders INNER JOIN orders_customers
ON orders.CUST_ORDER_ID = orders_customers.ID)
LEFT JOIN quoted_theory
ON orders.PART_ID = quoted_theory.PART_ID)
LEFT JOIN conversions
ON orders.PART_ID = conversions.PART_ID)
LEFT JOIN dbo_WO_Header
ON orders.CUST_ORDER_ID = dbo_WO_Header.PPC_Number
... then you could try that part as a subquery and inner join lines_qry to the subquery. It might get past the error.
SELECT *
FROM
(
SELECT *
FROM
(((orders INNER JOIN orders_customers
ON orders.CUST_ORDER_ID = orders_customers.ID)
LEFT JOIN quoted_theory
ON orders.PART_ID = quoted_theory.PART_ID)
LEFT JOIN conversions
ON orders.PART_ID = conversions.PART_ID)
LEFT JOIN dbo_WO_Header
ON orders.CUST_ORDER_ID = dbo_WO_Header.PPC_Number
) AS sub
INNER JOIN lines_qry
ON sub.CUST_ORDER_ID = lines_qry.WORKORDER_BASE_ID
If any other table besides orders includes a field named CUST_ORDER_ID, you will need something other than SELECT * within the subquery to avoid ambiguity.

SELECT *
FROM
(
SELECT *
FROM
(((orders INNER JOIN orders_customers
ON orders.CUST_ORDER_ID = orders_customers.ID)
LEFT JOIN quoted_theory
ON orders.PART_ID = quoted_theory.PART_ID)
LEFT JOIN conversions
ON orders.PART_ID = conversions.PART_ID)
LEFT JOIN dbo_WO_Header
ON orders.CUST_ORDER_ID = dbo_WO_Header.PPC_Number
) AS sub
INNER JOIN lines_qry
ON sub.CUST_ORDER_ID = lines_qry.WORKORDER_BASE_ID

Related

Big Query : LEFT OUTER JOIN cannot be used without a condition that is an equality of fields from both sides of the join

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
)

SQL inner join multi part identifier could not be bound

I have a stored procedure with a bunch of joins I can not figure out why this is not working - I get an error:
The multi-part identifier "[table.column]" could not be bound.
This is an altered bit of SQL the original is -
dbo.Release
INNER JOIN
dbo.Cartridge
INNER JOIN
dbo.PriceClass AS PriceClass ON dbo.Cartridge.PriceClassId = PriceClass.Id
INNER JOIN
dbo.CartridgeType ON dbo.Cartridge.CartridgeTypeId = dbo.CartridgeType.Id
ON dbo.Release.Id = dbo.Cartridge.ReleaseId
INNER JOIN
dbo.OemSegmentation
INNER JOIN
dbo.OemProduct ON dbo.OemSegmentation.OemProductId = dbo.OemProduct.Id
INNER JOIN
dbo.OemPlatform ON dbo.OemSegmentation.OemPlatformId = dbo.OemPlatform.Id
INNER JOIN
dbo.OemMediaType ON dbo.OemSegmentation.OemMediaTypeId = dbo.OemMediaType.Id
ON dbo.CartridgeType.Id = dbo.OemSegmentation.SupplCartTypeId
OR dbo.CartridgeType.Id = dbo.OemSegmentation.CartridgeTypeId
LEFT OUTER JOIN
dbo.CartridgeCoverage ON dbo.Cartridge.Id = dbo.CartridgeCoverage.CartridgeId
What I am trying to change it to -
dbo.Release
INNER JOIN
dbo.Cartridge
INNER JOIN
dbo.PriceClass AS PriceClass ON dbo.Cartridge.PriceClassId = PriceClass.Id
INNER JOIN
dbo.CartridgeType ON dbo.Cartridge.CartridgeTypeId = dbo.CartridgeType.Id
ON dbo.Release.Id = dbo.Cartridge.ReleaseId
INNER JOIN
dbo.OemProduct ON OemSegmentation.OemProductId = dbo.OemProduct.Id
INNER JOIN
dbo.OemPlatform ON dbo.OemSegmentation.OemPlatformId = dbo.OemPlatform.Id
INNER JOIN
dbo.OemMediaType ON dbo.OemSegmentation.OemMediaTypeId = dbo.OemMediaType.Id
LEFT OUTER JOIN
dbo.CartridgeCoverage ON dbo.Cartridge.Id = dbo.CartridgeCoverage.CartridgeId
The error happens on these lines
INNER JOIN
dbo.OemProduct ON OemSegmentation.OemProductId = dbo.OemProduct.Id
INNER JOIN
dbo.OemPlatform ON dbo.OemSegmentation.OemPlatformId = dbo.OemPlatform.Id
INNER JOIN
dbo.OemMediaType ON dbo.OemSegmentation.OemMediaTypeId = dbo.OemMediaType.Id
Once you have aliased your table, use the alias to use TWO PART names for columns. i.e [TableAlias].[ColumnName]
I belive you have use column namd Id in all your tables commonly, so whenever you are picking Id column just go for [TableName].Id.
It seems you missed join: "INNER JOIN dbo.OemSegmentation"

Convert fractions into decimal in sql using a function and select statements

Every time I try to run the following in Microsoft SQL Server Management Studio, I get an error message
A SELECT statement that assigns a value to a variable must not be combined with data-retrieval operations
Is there anyway at all to run this in one statement?
The reason why I'm calling a function in this statement (dbo.ufn_ConvertJambDepthFractionToNumber) is because the dbo.CDS_Shipments_Door_Overall_Jamb_Depth.InstructionValue AS [Jamb Depth] column spits out values like 4 1/6", 3 1/4", 6 9/16". I'm using that function to try to convert the varchar values (4 1/6", 3 1/4", 6 9/16") into decimals.
If there is a better way to do that, I'm all ears.
use BeechworthProdWTS
declare #jamb_depth as varchar
SELECT DISTINCT
dbo.QuoteShippingAddress.Name AS [CDS Location],
dbo.QuoteShippingAddress.Address1 AS [Quote Shipping Address1],
dbo.CDS_Shipments_Door_Overall_Jamb_Depth.InstructionValue AS [Jamb Depth],
dbo.CDS_Shipments_Door_Count_view.Doors,
dbo.CDS_Shipments_Screen_Count_view.Screens,
dbo.CDS_Shipments_Windows_Count_view.Windows,
dbo.LineItemMaster.LineNumber,
#jamb_depth = dbo.CDS_Shipments_Door_Overall_Jamb_Depth.InstructionValue,
dbo.ufn_ConvertJambDepthFractionToNumber(#jamb_depth)
FROM
dbo.Quotes
INNER JOIN
dbo.QuoteShippingAddress WITH (NOLOCK) ON dbo.Quotes.QuoteID = dbo.QuoteShippingAddress.QuoteID
INNER JOIN
dbo.Clients WITH (NOLOCK) ON dbo.Quotes.ClientID = dbo.Clients.ClientID
INNER JOIN
dbo.CustomerProjectInformation WITH (NOLOCK) ON dbo.Quotes.QuoteID = dbo.CustomerProjectInformation.QuoteID
INNER JOIN
dbo.LineItemMaster WITH (NOLOCK) ON dbo.Quotes.QuoteID = dbo.LineItemMaster.QuoteID
INNER JOIN
dbo.LineItems WITH (NOLOCK) ON dbo.LineItemMaster.LineItemMasterID = dbo.LineItems.LineItemMasterID
INNER JOIN
dbo.WorkOrders WITH (NOLOCK) ON dbo.LineItems.LineItemID = dbo.WorkOrders.LineItemID
LEFT OUTER JOIN
dbo.CDS_Shipments_Door_Count_view WITH (NOLOCK) ON dbo.LineItems.LineItemID = dbo.CDS_Shipments_Door_Count_view.LineItemID
LEFT OUTER JOIN
dbo.CDS_Shipments_Door_Overall_Jamb_Depth WITH (NOLOCK) ON dbo.LineItems.LineItemID = dbo.CDS_Shipments_Door_Overall_Jamb_Depth.LineItemID
LEFT OUTER JOIN
dbo.CDS_Shipments_Screen_Count_view WITH (NOLOCK) ON dbo.LineItems.LineItemID = dbo.CDS_Shipments_Screen_Count_view.LineItemID
LEFT OUTER JOIN
dbo.CDS_Shipments_Windows_Count_view WITH (NOLOCK) ON dbo.LineItems.LineItemID = dbo.CDS_Shipments_Windows_Count_view.LineItemID
Since you say you are pretty new to SQL I reformatted this using aliases so you can see how much difference it make visually. This doesn't affect performance but it does keep the developer sane. Also, not really sure what you are trying to do with your scalar but maybe trying to get the value for each row?
Cleaned up your query might look something like this.
SELECT DISTINCT
qsa.Name AS [CDS Location],
qsa.Address1 AS [Quote Shipping Address1],
sdojd.InstructionValue AS [Jamb Depth],
sdcv.Doors,
sscv.Screens,
swcv.Windows,
lim.LineNumber,
--#jamb_depth = sdojd.InstructionValue, --not really sure what you are trying to do here
--dbo.ufn_ConvertJambDepthFractionToNumber(#jamb_depth)
JambDepth = dbo.ufn_ConvertJambDepthFractionToNumber(sdojd.InstructionValue)
FROM dbo.Quotes q
INNER JOIN dbo.QuoteShippingAddress qsa ON q.QuoteID = qsa.QuoteID
INNER JOIN dbo.Clients c ON q.ClientID = c.ClientID
INNER JOIN dbo.CustomerProjectInformation cpi ON q.QuoteID = cpi.QuoteID
INNER JOIN dbo.LineItemMaster lim ON q.QuoteID = lim.QuoteID
INNER JOIN dbo.LineItems li ON lim.LineItemMasterID = li.LineItemMasterID
INNER JOIN dbo.WorkOrders wo ON li.LineItemID = wo.LineItemID
LEFT OUTER JOIN dbo.CDS_Shipments_Door_Count_view sdcv ON li.LineItemID = sdcv.LineItemID
LEFT OUTER JOIN dbo.CDS_Shipments_Door_Overall_Jamb_Depth sdojd ON li.LineItemID = sdojd.LineItemID
LEFT OUTER JOIN dbo.CDS_Shipments_Screen_Count_view sscv ON li.LineItemID = sscv.LineItemID
LEFT OUTER JOIN dbo.CDS_Shipments_Windows_Count_view swcv ON li.LineItemID = swcv.LineItemID

POSTGRESQL - UNNEST function not work in LINUX [duplicate]

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;

Left Join not working

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