Trouble with WHERE EXIST subquery of a LEFT JOIN - sql

I am trying to run a Left Join in the MS Access SQL. I am trying to Left Join my "OldPE" table to New "1 PE" table and update my column labeled "Line Num". There is no primary key in these tables so I am linking them through a series of conditions. Here is my code so far (excuse the poor formatting I am new and still learning SQL).
UPDATE [1 PE]
LEFT JOIN OldPE ON ([1 PE].SumRes = OldPE.SumRes)
AND ([1 PE].[Project Code] = OldPE.[Project Code])
AND ([1 PE].[DeptID] = OldPE.[DeptID])
AND ([1 PE].[Res Code] = OldPe.[Res Code])
AND ([1 PE].[Explain The Cost] LIKE OldPE.[Explain The Cost])
AND ([1 PE].Notes LIKE OldPE.Notes)
SET [1 PE].[Line Num] = [OldPE].[Line Num];
There are a lot of rows that have null or blank values in their "Explain The Cost" and "Notes" columns. I used a like statement because some of the notes that I want together vary slightly due to spelling mistakes and such. However now that I use the "like" it won't return the rows with a null value for these columns. The SQL code wont accept a WHERE EXISTS (I may also just be writing it wrong).
How do I get these null values to still be returned while using the Like command

Use ISNULL to join back to the original value if it is null. (This will include the null values in the results.)
AND ([1 PE].[Explain The Cost] LIKE ISNULL(OldPE.[Explain The Cost],[1 PE].[Explain The Cost]))

Related

I'm having issues getting the NZ function working in a query

I'm trying to tie a description to group codes to use in another table. Unfortunately the data is from a very old database and didn't have very good requirements for fields when it was initially created. So now I have a number of fields for part number group codes that were blank. I'm trying to convert these null values to say "blank". I've tried this many different ways and cannot get the nz function to modify the data in any way.
In the provided code snippet I have tried using the nz function only after select, only after from, and in both places as shown.
SELECT [Part Numbers].Part, nz([Part Numbers].Group,"Blank"), [Group Codes].Description
FROM [Part Numbers]
INNER JOIN [Group Codes] ON nz([Part Numbers].[Group],"Blank") = [Group Codes].[Group Code];
That query doesn't return records where Group field is Null. It can't even be displayed in query design with that join.
Consider RIGHT JOIN:
SELECT [Part Numbers].Part, Nz([Part Numbers].Group,"Blank") AS Expr1, [Group Codes].Description
FROM [Group Codes] RIGHT JOIN [Part Numbers] ON [Group Codes].[Group Code] = [Part Numbers].Group;

How to make a sub-query based on query results in SQL

I'm currently trying to query a list of our assembly items, along with their corresponding components.
I've been trying this query a few different ways, here is where I'm currently at (closest I've gotten)
SELECT inv_mast.item_id AS [Item ID]
,inv_mast.item_desc AS [Item Description]
,IMC.item_id AS [Component Item ID]
FROM inv_mast
INNER JOIN assembly_line ON inv_mast.inv_mast_uid = assembly_line.inv_mast_uid
LEFT JOIN inv_mast IMC ON assembly_line.component_inv_mast_uid = inv_mast.inv_mast_uid
WHERE inv_mast.item_id = 'LFV-SV59Z-2ZGD-LOGO-L'
In the "Assembly_line" table there is a Component_inv_mast_uid which I need to use to query our Item ID's for the components (inv_mast joins to assembly_line on the inv_mast_uid)
It should export something like this:
LFV-SV59Z-2ZGD-LOGO-L (LFV-SV59Z-2ZGD-L)
LFV-SV59Z-2ZGD-LOGO-L (Print Fee)
I forgot to mention what is currently exporting.
When I run this query, it provides most information correct, however the "Component Item ID" column is returning Null, and I'm not sure why.
I've only had experience so far with joining basic tables, so subqueries are very new to me.
try to use
WHERE inv_mast.item_id like 'LFV-SV59Z-2ZGD-LOGO-L%'
instead of = 'LFV-SV59Z-2ZGD-LOGO-L'

MS Access SQL Query Not Exist

I have been stuck on trying to figure how to return data that is in one table but not the other. I thought an outter join would work, but it seems that Access does not allow that.
My SQL is returning results if a record exists in the MonthlyTargets_0_SPARTN_qry but if there is not record then no data is being returned. I would like to display a 0 if there are not records.
My sql is:
SELECT REF_TestCategory_tbl.CategoryID
,MonthlyTargets_0_SPARTN_qry.[Supervisor Id] AS TestOfficerID
,Count(MonthlyTargets_0_SPARTN_qry.[Sheet ID]) AS Actuals
,MonthlyTargets_0_SPARTN_qry.ComplianceMonth
FROM MonthlyTargets_0_SPARTN_qry
INNER JOIN (
REF_TestCategory_tbl INNER JOIN REF_TestCatalog_tbl ON REF_TestCategory_tbl.CategoryID = REF_TestCatalog_tbl.TestCategory
) ON MonthlyTargets_0_SPARTN_qry.[Test Number] = REF_TestCatalog_tbl.TestID
GROUP BY REF_TestCategory_tbl.CategoryID
,MonthlyTargets_0_SPARTN_qry.[Supervisor Id]
,MonthlyTargets_0_SPARTN_qry.ComplianceMonth
ORDER BY REF_TestCategory_tbl.CategoryID;
Which returns:
CategoryID TestOfficerID Actuals ComplianceMonth
1 3062 26 1/1/2020
1 3062 6 2/1/2020
2 3062 2 1/1/2020
3 3062 2 1/1/2020
3 3062 1 2/1/2020
if there are no records for feb, I need it to reurn 0 in Actuals
Thank you
If your 'ComplianceMonth' Values consistently exists regardless of your adjacent data(Meaning if the adjacent data returned for your ComplianceMonth is NULL) then you could do something like this.
SELECT REF_TestCategory_tbl.CategoryID,
MonthlyTargets_0_SPARTN_qry.[Supervisor Id] AS TestOfficerID,
coalesce(Count(MonthlyTargets_0_SPARTN_qry.[Sheet ID]),0) AS Actuals,
MonthlyTargets_0_SPARTN_qry.ComplianceMonth
FROM dbo.MonthlyTargets_0_SPARTN_qry RIGHT OUTER JOIN
dbo.REF_TestCategory_tbl RIGHT OUTER JOIN
dbo.REF_TestCatalog_tbl ON REF_TestCategory_tbl.CategoryID = REF_TestCatalog_tbl.TestCategory ON MonthlyTargets_0_SPARTN_qry.[Test Number] = REF_TestCatalog_tbl.TestID
GROUP BY REF_TestCategory_tbl.CategoryID, MonthlyTargets_0_SPARTN_qry.[Supervisor Id], MonthlyTargets_0_SPARTN_qry.ComplianceMonth
ORDER BY REF_TestCategory_tbl.CategoryID
Hope this Helps.
MS-Access DOES allow outer joins in its SQL. You can do both a LEFT JOIN or a RIGHT JOIN.
MS-Access does not include a statement for a full-outer-join. However, if you want to do a full-outer-join you can do it with a UNION ALL of a specific LEFT JOIN and a specific RIGHT JOIN. The instructions to do a full-outer-join are the following:
You do a “LEFT JOIN” (enclosed in a Select operation) between the two input record-lists. If one of the two input record-lists has one (or more) fields that for sure cannot be Null, that will be the left input record-list. The “ON” Boolean expression is the one that you want for the Full-Outer-Join.
If the left record-list has one (or more) fields that for sure cannot be Null, you skip this step. Otherwise, you do a Cross-Join between the left record-list and a record-list having only one record with one non-Null field (it can be exactly the same Select over “T_Numbers” in the example above, highlighted in green). The Cross-Join is enclosed in a Select that exposes all the fields from the Cross-Join operation, including the field “Num” from “T_Numbers” (with another field name, if you want).
You do a “RIGHT JOIN” having the same right input record-list from point 1. Its left record-list is either the Select from point 2, or the left input record-list from point 1, as corresponds (see point 2). The “ON” expression must be exactly the same as the one of the “LEFT JOIN” from point 1.
The “RIGHT JOIN” from point 3 is enclosed in a Select that exposes all the fields from the left and right input record-lists from point 1. This Select has the “WHERE” expression “IsNull(field)”, where “field” is either the “Num” field from point 2, or the field from left input record-list that for sure cannot be Null, as corresponds (see point 2).
You do a “UNION ALL” with the Select enclosing the “RIGHT JOIN” from point one and the Select enclosing the “RIGHT JOIN” from point 4.
More information at LightningGuide.net.

Invalid results from SQL Server "NOT IN" clause

I have run a query on our SQL Server 2012 which returned no results. I discovered that this was incorrect and I SHOULD have gotten 16 records. I changed the query and get the answer expected but I am at a loss to understand why my original query did not work as expected.
So my ORIGINAL query which returned no results was:
SELECT
WPB.[ID number]
FROM
[Fact].[REPORT].[WPB_LIST_OF_IDS] WPB
WHERE
[ID number] NOT IN (SELECT DISTINCT IdNumber
FROM MasterData.Dimension.Customer DC)
The reworked query is this:
SELECT
WPB.[ID number]
FROM
[Fact].[REPORT].[WPB_LIST_OF_IDS] WPB
LEFT JOIN
MasterData.Dimension.Customer DC ON WPB.[ID number] = DC.IdNumber
WHERE
DC.IdNumber IS NULL
Can anyone tell me WHY the first query (which incidentally runs in fractions of a second vs the 2nd which takes a minute) does not work? I don't want to repeat this mistake in the future!
Don't use not in with a subquery. It doesn't work the way you expect with NULL values. If any value returned by the subquery is NULL, then no rows are returned at all.
Instead, use not exists. This has the semantics that you expect:
select wpb.[ID number]
from [Fact].[REPORT].[WPB_LIST_OF_IDS] wpb
where not exists (select 1
from MasterData.Dimension.Customer dc
where wpb.[ID number] = dc.IdNumber
);
Of course, the left join method also works.

SQL Query extremely slow when including NOT LIKE or a current row reference in a subquery

I have the following query in SQL Server 2008 R2:
SELECT
DateName(month, DateAdd(month, [sfq].[fore_quart_month], -1)) AS [Month],
[sfq].[fore_quart_so_rev] AS [Sales Orders Revenue],
[sfq].[fore_quart_so_mar] AS [Sales Orders Margin],
[sfq].[fore_quart_mac_rev] AS [MAC Revenue],
[sfq].[fore_quart_mac_mar] AS [MAC Margin],
[sfq].[fore_quart_total_rev] AS [TOTAL Revenue],
[sfq].[fore_quart_total_mar] AS [TOTAL Margin],
(SELECT SUM([FORE].[Revenue])
FROM [SO_Opportunity][SO]
LEFT JOIN [SO_Type] ON [SO].[SO_Type_RecID] = [SO_Type].[SO_Type_RecID]
LEFT JOIN [SO_Opportunity_Audit][soa] ON [so].[Opportunity_RecID] = [soa].[Opportunity_RecId]
LEFT JOIN [SO_Opportunity_Audit_Value][soav] ON [soa].[SO_Opportunity_Audit_RecId] = [soav].[SO_Opportunity_audit_recid]
LEFT JOIN [SO_Forecast_dtl] [FORE] ON [SO].[Opportunity_RecID] = [FORE].[Opportunity_RecID]
WHERE ([SO_Type].[Description] NOT LIKE '%MAC%' AND [SO_Type].[Description] NOT LIKE '%Maint%')
AND YEAR([soa].[last_Updated_utc]) = #p_year AND MONTH([soa].[last_updated_utc]) = [sfq].[fore_quart_month]
AND [soav].[audit_value] LIKE '%Closed - Won%' AND [soav].[audit_token] = 'new_value'
AND [so].[SO_Opp_Status_RecID] = 7) AS [Rev]
FROM
[authmanager2].[dbo].[sales_forecast_quarterly][sfq]
WHERE
[sfq].[fore_quart_year] = #p_year AND [sfq].[fore_quart_loc] = 'w'
ORDER BY
[sfq].[fore_quart_month]
The issue is that when including the NOT LIKE filters and the [sfq].[fore_quart_month] reference in the subquery, it runs incredibly slow (minutes), but if I remove the NOT LIKE filters or if I hard set the value instead of use the [sfq].[fore_quart_month] (which obviously means every calculation will use the wrong month except the one I hard coded), then the query runs in less than a second.
Any suggestions?
The LIKE queries with wild cards on both ends are very slow. Example: %MAC%
If you really need to search on that, consider creating a persisted computed boolean field and searching on that. Something like:
ALTER TABLE SO_Type
ADD IsMac AS CASE WHEN [Description] LIKE '%MAC%' THEN 1 ELSE 0 END PERSISTED
GO
OR
As an alternative, set ISMac whenever data is inserted
Small tip: you can group by month and join subquery to main datasource in from clause. This will let (which is not must) server perform subquery only once. And please note my comment above.
...
FROM [authmanager2].[dbo].[sales_forecast_quarterly][sfq]
INNER JOIN
(
SELECT SUM([FORE].[Revenue]) as [Revenue], MONTH([soa].[last_updated_utc]) as [Month]
FROM [SO_Opportunity][SO]
INNER JOIN [SO_Type] ON [SO].[SO_Type_RecID] = [SO_Type].[SO_Type_RecID]
...
GROUP BY MONTH([soa].[last_updated_utc])
) rev on rev.[Month] = [sfq].[fore_quart_month]