MS Access - Ambiguous outer joins? - sql

I am not sure why my query is netting me the following error:
The SQL statement could not be executed because it contains ambiguous outer joins. To force one of the joins to be performed first, create a separate query that performs the firm join and then include that query in your SQL statement.
This is my query, I only see one join:
SELECT PC.[Mother_Board_Name] & ',' & PC.[Mother_Board_Manufacturer]
FROM PersonalComputerHardware PC, Registers R
WHERE ',' & R.[Names].Value & ',' LIKE '*,' & PC.[Computer_ID] & ',*';
R.Names.Value is a reference to a multi-value field, by the way. I don't understand this error message because I am only using one Cross JOIN

Try this:
SELECT PC.Mother_Board_Name & ',' & PC.Mother_Board_Manufacturer
FROM PersonalComputerHardware PC
INNER JOIN Registers R ON R.Names LIKE '*,' & PC.Computer_ID & ',*'
Assuming your actual logic is correct, this should work.
However your logic is probably not correct. At best it will only match Computer_ID that is in the middle (not first or last) unless your Names has commas at the beginning and end as well.

Related

Complex JOINS in Access SQL difficult to convert to JET OLEDB

I'm a long time follower of Stack overflow but this is my first post. I'm hoping the community can help.
I have a successful Access Query that returns the required results - Perfect!
HOWEVER, I'm trying to return the same using OLEDB connection to the database within an ASP script. This is all legacy stuff however we are allowing web access to this legacy information.
MS Access (2016) shows Query as this... (works)
SELECT [EventName] & ": " & [RoundCaption] AS RoundTitle, ChunkEntryTable.WinPos
FROM ((EventTable INNER JOIN EventRoundTable ON EventTable.EventId = EventRoundTable.EventId) INNER JOIN ((RoundHeatTable INNER JOIN ChunkTable ON RoundHeatTable.RoundHeatId = ChunkTable.RoundHeatId) INNER JOIN (EventEntryTable INNER JOIN ChunkEntryTable ON EventEntryTable.EventEntryId = ChunkEntryTable.EventEntryId) ON ChunkTable.ChunkId = ChunkEntryTable.ChunkId) ON EventRoundTable.RoundKeyId = RoundHeatTable.RoundKeyId) LEFT JOIN EventEntryMemberTable ON EventEntryTable.EventEntryId = EventEntryMemberTable.EventEntryId
WHERE (((EventEntryTable.Entry1Id)=[EntryId])) OR (((EventEntryTable.Entry2Id)=[EntryId])) OR (((EventEntryTable.Entry3Id)=[EntryId])) OR (((EventEntryMemberTable.MemberId)=[EntryId]))
ORDER BY EventTable.SortIdx, EventRoundTable.RoundId DESC , EventRoundTable.IsRepechage DESC;
Doing this in OLEDB. Connection string as follows...
<%
' FileName="Connection_ado_conn_string.htm"
' Type="ADO"
' DesigntimeType="ADO"
' HTTP="true"
' Catalog=""
' Schema=""
Dim MM_csresultdb_STRING
MM_csresultdb_STRING = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=xyz.mde;Jet OLEDB:Database Password=xxxxxxxxx;"
%>
Connection works perfectly but I can't seem to get the SQL command to work. I get "No value given for one or more required parameters".
NOTE: I have replaced [EntryID] in 4 places with a valid value and it works perfectly in Access just not outside of Access using OLEDB. Here's what the SQL is I'm using...
SELECT EventTable.EventName & ": " & EventRoundTable.RoundCaption AS RoundTitle, ChunkEntryTable.WinPos FROM
((EventTable INNER JOIN EventRoundTable ON EventTable.EventId = EventRoundTable.EventId) INNER JOIN
((RoundHeatTable INNER JOIN ChunkTable ON RoundHeatTable.RoundHeatId = ChunkTable.RoundHeatId) INNER JOIN
(EventEntryTable INNER JOIN ChunkEntryTable ON EventEntryTable.EventEntryId = ChunkEntryTable.EventEntryId) ON ChunkTable.ChunkId = ChunkEntryTable.ChunkId) ON ChunkTable.ChunkId = ChunkEntryTable.ChunkId)
ON EventRoundTable.RoundKeyId = RoundHeatTable.RoundKeyId)
WHERE ((EventEntryTable.Entry1Id)=4741) OR ((EventEntryTable.Entry2Id)=4741) OR ((EventEntryTable.Entry3Id)=4741)
ORDER BY EventTable.SortIdx, EventRoundTable.RoundId DESC , EventRoundTable.IsRepechage DESC;
FOUND PROBLEM ** See answer below
FOUND PROBLEM ** It's to do with this part of the SQL...
[EventName] & ": " & [RoundCaption] AS RoundTitle
Changed to
[EventName], [RoundCaption] AS RoundTitle
and it works but gives me two separate fields rather than the one concatenated field called "RoundTitle". So I'll join the two result fields during the display output rather than at the query stage.
Whew! That many days to figure out. Thanks to the comments that kinda steered me in that direction of the AS part of the statement.

ConcatRelated() - query or tables

I have similar issue to this question Combine values from related rows into a single concatenated string value.
I've got two queries:
This is what it looks like now without ConcatRelated():
I need to get return:
I tried to use this SQL:
SELECT DISTINCT
Q_Fakt1.FakturaID,
Q_Fakt1.DatumVystavenia,
Q_Fakt1.DatumSplatnosti,
Q_Fakt2.Pismeno,
ConcatRelated(
"pismeno",
"Q_Fakt2",
"FakturaID = '" & [Q_Fakt1]![FakturaID] & "'"
) AS Letters
FROM Q_Fakt1 INNER JOIN Q_Fakt2 ON Q_Fakt1.FakturaID = Q_Fakt2.FakturaID;
Result is 7× popup:
ConcatRelated() Error3464: Data type mismatch in criteria expression.
I did the same with Tables but I have little bit more complicated Relations so...
https://i.stack.imgur.com/TM7Cu.png
SQL:
SELECT DISTINCT
Faktury.FakturaID,
Kategorie.Oznacenie,
Faktury.DatumVystavenia,
FakturujemVam.FakturujemVamID,
FakturyDetaily.FakturujemVam,
[DatumVystavenia]+[splatnostFaktury] AS DatumSplatnosti,
ConcatRelated("Oznacenie","kategorie","FakturaID = '" & [FakturaID] & "'") AS Letters
FROM Kategorie INNER JOIN (Faktury INNER JOIN (FakturujemVam INNER JOIN FakturyDetaily ON FakturujemVam.FakturujemVamID = FakturyDetaily.FakturujemVam) ON Faktury.FakturaID = FakturyDetaily.Faktura) ON Kategorie.KategoriaID = FakturujemVam.Kategoria;
Result is 6× popup:
ConcatRelated() Error3061: Too Few parameters. Excepted 1.
Where did I go wrong? Thank you for Help
That's because you're using string delimiters when you're not using a string.
Remove those delimiters, and it will work fine:
ConcatRelated("Oznacenie","kategorie","FakturaID = " & [FakturaID] ) AS Letters
SOLVED:
STEP 1
Create Query to merge more tables in one
Datasheet View
Design View
STEP 2
Create another Query & Use ConcatRelated()
Design View
SQL:
SELECT
Q_Part_Bill_Num2.NumBill,
Q_Part_Bill_Num2.C_Mark,
ConcatRelated(
"C_Mark",
"Q_Part_Bill_Num2",
"Q_Part_Bill_Num2!NumBill = " & [Q_Part_Bill_Num2]![NumBill]
) AS PartBillNum2
FROM Q_Part_Bill_Num1 INNER JOIN Q_Part_Bill_Num2 ON Q_Part_Bill_Num1.NumBill = Q_Part_Bill_Num2.NumBill;
STEP 3 - Optional
Edit MODULE to delete / change separator ", "
STEP 4
Create One Last Query to Concatenate everything together.
Design View
SQL:
SELECT DISTINCT
Q_Part_Bill_Num1.PartBillNum1,
Q_Part_Bill_Num3.PartBillNum2,
[PartBillNum1] & [PartBillNum2] AS [Full]
FROM
(T_Bills INNER JOIN Q_Part_Bill_Num1 ON T_Bills.Bills_ID = Q_Part_Bill_Num1.Bills_ID)
INNER JOIN (Q_Part_Bill_Num2 INNER JOIN Q_Part_Bill_Num3
ON (Q_Part_Bill_Num2.NumBill = Q_Part_Bill_Num3.NumBill)
AND (Q_Part_Bill_Num2.C_Mark = Q_Part_Bill_Num3.C_Mark))
ON Q_Part_Bill_Num1.NumBill = Q_Part_Bill_Num2.NumBill;
Use DISTINCT to avoid duplicates.
I Hope this will help someone.
Thank you all, for your time :)

How do I run an SQL update query using a like statement

I am trying to update a field in a table using an SQL update query where there is a like statement referencing a value in another table. They syntax unfortunately is not working. Below is my code. In short, I am trying to put a '1' in the field 'Query07ParolaChiave' in the table 'tblSearchEngine01' when the value located in table 'tblsearchengine07' is present in the field 'tblMasterListOfEventsNotes' located in the table 'tblSearchEngine01'. I think my code is almost complete but there is a syntax issue which i cant find.
st_sql = "UPDATE tblSearchEngine01, tblSearchEngine07 SET tblSearchEngine01.Query07ParolaChiaveSelect = '1' WHERE ((([tblSearchEngine01].[tblMasterListOfEventsNotes]) Like " * " & [tblsearchengine07].[ParolaChiave] & " * "))"
Application.DoCmd.RunSQL (st_sql)
I suggest you 2 solutions :
This one is using EXISTS functions, and will check for each row in tblSearchEngine01 if there is a matching value in tblsearchengine07
UPDATE
tblSearchEngine01
SET
tblSearchEngine01.Query07ParolaChiaveSelect = '1'
WHERE
EXISTS (SELECT 1
FROM tblsearchengine07
WHERE [tblSearchEngine01].[tblMasterListOfEventsNotes] Like '*' & [tblsearchengine07].[ParolaChiave] & '*')
This one is more performant because it uses JOIN
UPDATE
tblSearchEngine01
INNER JOIN tblsearchengine07
ON [tblSearchEngine01].[tblMasterListOfEventsNotes] Like '*' & [tblsearchengine07].[ParolaChiave] & '*'
SET
tblSearchEngine01.Query07ParolaChiaveSelect = '1'
I read something like in ADO/VBA, you have to use % instead of * as the wildcard.
You can have more information on wildcard and LIKE comparator here
UPDATE
Why the '1' after select in your first solution?
EXISTS (SELECT 1 ... is better for performance because it return only the number 1 instead of fields, anyway EXISTS just stop the excecution after 1 element found.
'Performant' means more consuming in regards to space and memory?
JOIN is more performant in term of time of execution, RDBMS are far better at joining tables than using subquery, in some rare case, it's more interesting to use the 1st solution.
Also, any initial thoughts as to why my original solution (coming straight from an Access Query which works) does not function?
I cannot really know but perhaps it's because of " * ", because you are saying SPACE + * + SPACE + VALUE + SPACE + * + SPACE. For ex : 'John' LIKE ' John '
May be with "*" instead of " * " could solve it...
I have no other track, I'm not Access sql developper, I usually play around Sql server/Oracle/mySql, hope it helped. ;)
Try to change your like this way:
... Like '*" & tblsearchengine07.parolachiave & "*'))"
The like statement go into the WHERE clause.
If you do want to use LIKE without you care about caps letters, then you can use it like this:
LIKE COLUMN_NAME = '%WhatYouLike%'
My suggestion is:
Use a table variable (#Table) with a unique/primary key coming from the table to be updated.
SELECT all the data to be updated (you can add the like statement here) and then INSERT that in the created table variable.
Construct the UPDATE statement with an INNER JOIN to the table variable matching with the unique/primary key.
I know this may take a lot of steps but believe me these are more efficient than using a black list approach.

Query Syntax help!

I am running this query in Access 2007 and getting a syntax error on this query
UPDATE INQuery SET Awords=(SELECT Coalsce("SELECT (parentdesc & '/' & keyword) From Awords LEFT JOIN INQuery ON Awords.id=INQuery.item_id",";"))
WHERE Awords.id=IN_Query.item_id;
System error in query expression
'(SELECT Coalsce("SELECT (parentdesc &
'/' & keyword) From Awords LEFT JOIN
INQuery ON
Awords.id=INQuery.item_id",";"))'.
When I run the query expression separately I get the desired result.
NOTE: To see what Coalsce function is
please refer
VBA + String splitting
Do you actually need the additional SELECT?
UPDATE INQuery SET Awords=Coalsce(...) WHERE ...
Could it be that it's Coalesce not Coalsce? (typo?)

Syntax Error in Join Operation in MS-Access when splitting and comparing records

Above error message occurs with this statement:
SELECT f.fullname INTO SummaryJudgment_FinalForgottenWithMiddle
FROM (
(SELECT Left([aname],InStr(1,[aname],",")-1)) As lastname FROM
SummaryJudgment_FinalForgotten) & " " & (SELECT
RIGHT([aname],InStr(1,[aname],",")+1)) As firstname FROM
SummaryJudgment_FinalForgotten) & " " & (SELECT
summary_judgment.middle_initial AS middlename FROM summary_judgment)
) AS fullname
FROM SummaryJudgment_FinalForgotten AS f INNER JOIN summary_judgment
AS s ON f.lastname = s.last_name && f.firstname = s.first_name;
Basically this is what two tables look like (note they will have more fields than 1 where last or first name of different fields can be similar):
SummaryJudgment_FinalForgotten (table)
aname (field)
Leventhal,Raymond (data)
summary_judgment (table)
first_name(field)
Raymond (data)
last_name (field)
Leventhal (data)
middle_initial (field)
P (data)
Ultimately, I'm trying to create a new table that is like
SummaryJudgment_FinalForgotten but with the middle initial from
summary_judgment appended:
Leventhal,Raymond P
You do not need to write 3 select statements to concatenate the values into one field.
select left(...) & right(...) & initial AS fullname INTO SummaryJudgment_FinalForgottenWithMiddle
FROM SummaryJudgment_FinalForgotten
Are you trying to use two ampersands to represent a logical AND?
FROM SummaryJudgment_FinalForgotten AS f INNER JOIN summary_judgment
AS s ON f.lastname = s.last_name && f.firstname = s.first_name;
I don't think that's legal for Access' Jet/ACE database engines. Try it with the AND keyword in place of &&.
OTOH, I wonder if you can do something simpler.
SELECT last_name & "," & first_name & " " & middle_initial AS fullname
INTO SummaryJudgment_FinalForgottenWithMiddle
FROM summary_judgment;
This works:
SELECT left([aname],InStr(1,[aname],",")-1) & " "
& right([aname],Len(aname)-InStr(1,[aname],",")) & " "
& summary_judgment.middle_initial AS fullname
INTO SummaryJudgment_FinalForgottenWithMiddle
FROM SummaryJudgment_FinalForgotten, summary_judgment;
Though you might want this instead:
SELECT left([aname],InStr(1,[aname],",")-1) & ", "
& right([aname],Len(aname)-InStr(1,[aname],",")) & " "
& summary_judgment.middle_initial AS fullname
INTO SummaryJudgment_FinalForgottenWithMiddle
FROM SummaryJudgment_FinalForgotten, summary_judgment;
The second version gives you the comma after the last name. Note that Right counts from the right, which is why you have to subtract the InStr value from the length.
EDIT:
The code I gave above works with your sample data--one row in each table. With more rows, it gives a cross product of (LastName, FirstName) x MiddleInitial. It occurred to me that that might be the case, so I went back to my test & added a second row--it is true. So then I tried to write the join expression....
Access doesn't like this:
... ON left([aname],InStr(1,[aname],",")-1) = last_name ...
It throws the error "Join expression not supported." Changing it to this:
... ON (trim((left(SummaryJudgment_FinalForgotten.aname,InStr(1,[aname],",")-1))=trim(summary_judgment.last_name))) ...
results in a query that runs & creates the table, but doesn't create any rows (the same was true before I added the "trim" calls in an attempt to fix it).
So I tried specifying the table for all occurences of aname. No joy--until I realized that I was making the wrong comparison (derived-last to last and derived-first to last--oops).
Using the following FROM clause with either above SELECT ... INTO does work correctly:
FROM
SummaryJudgment_FinalForgotten INNER JOIN
summary_judgment ON
((left(SummaryJudgment_FinalForgotten.aname,InStr(1,SummaryJudgment_FinalForgotten.[aname],",")-1))=summary_judgment.last_name) AND
((right(SummaryJudgment_FinalForgotten.aname,Len(SummaryJudgment_FinalForgotten.aname)-InStr(1,SummaryJudgment_FinalForgotten.[aname],","))=summary_judgment.first_name));
It might even work correctly without the full qualification of each field now that I'm joining first to first & last to last (since there is no duplication across the tables), but having proven that it does work, I'm done.