SQL syntax error JOIN three tables - sql

I'm trying to join three tables. But I get this error
Syntax error(missing operator) in query expression STUDENTAI.mėgstamiausia_laida = TV_LAIDOS.id
LEFT JOIN MIESTAI
ON STUDENTAI.kilme = MIESTAI.koda'.
Here is my code
SELECT MIESTAI.pavadinimas, TV_LAIDOS.pavadinimas
FROM STUDENTAI
LEFT JOIN TV_LAIDOS
ON STUDENTAI.mėgstamiausia_laida = TV_LAIDOS.id
LEFT JOIN MIESTAI
ON STUDENTAI.kilme = MIESTAI.kodas
WHERE STUDENTAI.ugis > 190;
So what's wrong? Why I get this error?

This query:
SELECT MIESTAI.pavadinimas, TV_LAIDOS.pavadinimas
FROM STUDENTAI LEFT JOIN
TV_LAIDOS
ON STUDENTAI.mėgstamiausia_laida = TV_LAIDOS.id LEFT JOIN
MIESTAI
ON STUDENTAI.kilme = MIESTAI.kodas
WHERE STUDENTAI.ugis > 190;
Looks structurally correct for any database . . . except MS Access. In that system, you need parentheses around the joins:
SELECT MIESTAI.pavadinimas, TV_LAIDOS.pavadinimas
FROM (STUDENTAI LEFT JOIN
TV_LAIDOS
ON STUDENTAI.mėgstamiausia_laida = TV_LAIDOS.id
) LEFT JOIN
MIESTAI
ON STUDENTAI.kilme = MIESTAI.kodas
WHERE STUDENTAI.ugis > 190;
Note that this assumes that the tables and columns all exist and accented characters are allowed in column names and so on.

Your syntax is correct. Either the table MIESTAI doesn't exist, or the field names STIDENTAI.kilme, or MIESTAI.kadas doesn't exist.
Do you really want to join kilme and kadas?

This column name looks special:
STUDENTAI.mėgstamiausia_laida
It ran on my MySQL if I enclosed it in ``, i.e.
SELECT MIESTAI.pavadinimas, TV_LAIDOS.pavadinimas
FROM STUDENTAI
LEFT JOIN TV_LAIDOS
ON STUDENTAI.`mėgstamiausia_laida` = TV_LAIDOS.id
LEFT JOIN MIESTAI
ON STUDENTAI.kilme = MIESTAI.kodas
WHERE STUDENTAI.ugis > 190;

Related

Where is my syntax error in this SQL request?

I'm getting a syntax error near WHERE tbkay.keyword = 'ipsum' in the following request (using phpmyadmin):
SELECT tbart.articles_id FROM articles AS tbart
LEFT JOIN keywords AS tbkey
LEFT JOIN articles_keyword AS tbjoin
ON tbart.articles_id = tbjoin.articles_id
AND tbkey.id = tbjoin.keywords_id
WHERE tbkey.keyword = 'ipsum'
I don't get it.
You are not using an ON clause after each join:
SELECT tbart.articles_id
FROM articles AS tbart
INNER JOIN articles_keyword AS tbjoin ON tbart.articles_id = tbjoin.articles_id
INNER JOIN keywords AS tbkey ON tbkey.id = tbjoin.keywords_id
WHERE tbkey.keyword = 'ipsum'
I also changed the joins to INNER joins because the WHERE clause returns only matching rows.
If you want to keep the LEFT join and return all the rows of articles you must move this condition to the ON clause:
SELECT tbart.articles_id
FROM articles AS tbart
LEFT JOIN articles_keyword AS tbjoin ON tbart.articles_id = tbjoin.articles_id
LEFT JOIN keywords AS tbkey ON tbkey.id = tbjoin.keywords_id AND tbkey.keyword = 'ipsum'
Each JOIN should have a corresponding ON clause:
SELECT tbart.articles_id
FROM articles tbart LEFT JOIN
articles_keyword tbjoin
ON tbart.articles_id = tbjoin.articles_id LEFT JOIN
keywords tbkey
ON tbkey.id = tbjoin.keywords_id
WHERE tbkey.keyword = 'ipsum' ;
Your version has two JOINs and one ON, hence the error.

ORA-00933: SQL command not properly ended with INSERT INTO...SELECT statement

I fix my problem by chance, but I really want to know why it works :),
Here's the thing:
I get the ORA-00933: SQL command not properly ended Error when I execute the following SQL statement:
INSERT INTO BASP_DX.QLR#GT(BDCDYH, QSZT)
SELECT NVL(e.BDCDYH, ' '),b.LIFECYCLE AS QSZT
FROM DJ_DY a
LEFT JOIN DJ_XGDJGL d
ON d.ZSLBH = a.SLBH
LEFT JOIN DJ_DJB e
ON e.SLBH = d.FSLBH
AND e.SLBH = '0123456789'
LEFT JOIN DJ_QLRGL f
ON f.SLBH = e.SLBH
AND f.QLRLX = 'Person1'
LEFT JOIN DJ_QLRGL b
ON b.SLBH = a.SLBH
AND (b.QLRLX = 'Person2' OR (b.QLRLX = 'Person3' AND b.QLRID = f.QLRID))
WHERE a.SLBH = '12345'
AND e.SLBH IS NOT NULL
-- add the condition to ensure that
-- this statement and the second statement get the same result
AND b.QLRID IS NOT NULL
AND (a.LIFECYCLE = '0' OR a.LIFECYCLE IS NULL);
I remove all the unnecessary insert value, related table and condition from the original SQL statement, to focus on the problem part.
Then I google it, from this post I know the causes may be:
An INSERT statement with an ORDER BY clause or an INNER JOIN
A DELETE statement with an INNER JOIN or ORDER BY clause
An UPDATE statement with an INNER JOIN
Apparently, these are not my type. I didn't use the INNER JOIN and ORDER BY, all I use is LEFT JOIN statement, so I wonder it might be reason that I set too many conditions with the LEFT JOIN statement (such as LEFT JOIN DJ_QLRGL b), so I try move the conditions after WHERE clause, it looks like this:
INSERT INTO BASP_DX.QLR#GT(BDCDYH, QSZT)
SELECT NVL(e.BDCDYH, ' '),b.LIFECYCLE AS QSZT
FROM DJ_DY a
LEFT JOIN DJ_XGDJGL d
ON d.ZSLBH = a.SLBH
LEFT JOIN DJ_DJB e
ON e.SLBH = d.FSLBH
AND e.SLBH = '0123456789'
LEFT JOIN DJ_QLRGL f
ON f.SLBH = e.SLBH
AND f.QLRLX = 'Person1'
LEFT JOIN DJ_QLRGL b
ON b.SLBH = a.SLBH
-- this conditions move to WHERE clause
WHERE a.SLBH = '12345'
AND e.SLBH IS NOT NULL
-- here is the original LEFT JOIN condition
AND (b.QLRLX = 'Person2' OR (b.QLRLX = 'Person3' AND b.QLRID = f.QLRID))
AND (a.LIFECYCLE = '0' OR a.LIFECYCLE IS NULL);
Then it works!
But why?
I just want to know the reason for this situation.
Solution
the problem is triangular join, the LEFT JOIN conditions can't contain the condition concerning both the self join table, in this case, it's b.QLRID = f.QLRID, so when I remove the b.QLRID = f.QLRID condition, it works.
Firstly, the join of "DJ_QLRGL b" is not LEFT any more,
as WHERE condition excludes rows with no b counterpart found

Use query with InnerJoin

I'm trying to pass this query to inner join, but it does not know how?
This is the query I want to use InnerJoin with these values ​​where
SELECT
ticket.id_ticket,
ticket.id_rede,
historico.id_historico,
historico.id_ticket,
centro.id_centro,
eqpto.id_eqpto,
eqpto.nome,
centro.sigla_centro,
interface.id_interface,
interface.id_eqpto,
interface.desig,
tecnologia.descricao,
interface.id_tecnologia,
tecnologia.id_tecnologia,
eqpto.id_centro,
eqpto.id_rede
FROM
app_gpa_ticket.ticket,
app_gpa_ticket.historico,
dados_v3.centro,
dados_v3.eqpto,
dados_v3.interface,
dados_v3.tecnologia
WHERE
ticket.id_ticket = historico.id_ticket AND
centro.id_centro = eqpto.id_centro AND
eqpto.id_eqpto = interface.id_eqpto AND
eqpto.id_rede = ticket.id_rede AND
tecnologia.id_tecnologia = interface.id_tecnologia;
Thank you!
I think you are trying to go to the standard (explicit) syntax. What you need to do is take what would be your JOIN operators in the WHERE clause and move them near the table itself. What you need to know is what tables on the left (Before the INNER JOIN operator you are joining to the right (After the INNER JOIN operator)
SELECT
ticket.id_ticket,
ticket.id_rede,
historico.id_historico,
historico.id_ticket,
centro.id_centro,
eqpto.id_eqpto,
eqpto.nome,
centro.sigla_centro,
interface.id_interface,
interface.id_eqpto,
interface.desig,
tecnologia.descricao,
interface.id_tecnologia,
tecnologia.id_tecnologia,
eqpto.id_centro,
eqpto.id_rede
FROM app_gpa_ticket.ticket
INNER JOIN app_gpa_ticket.historico ON ticket.id_ticket = historico.id_ticket
INNER JOIN dados_v3.eqpto ON eqpto.id_rede = ticket.id_rede
INNER JOIN dados_v3.interface ON eqpto.id_eqpto = interface.id_eqpto
INNER JOIN dados_v3.centro ON centro.id_centro = eqpto.id_centro
INNER JOIN dados_v3.tecnologia ON tecnologia.id_tecnologia = interface.id_tecnologia

Postgresql - Having trouble performing left joins on multiple tables

I'm in the process of moving some Mysql queries over to Postgresql and I ran across this one that doesn't work.
select (tons of stuff)
from trip_publication
left join trip_collection AS "tc" on
tc.id = tp.collection_id
left join
trip_author ta1, (dies here)
trip_person tp1,
trip_institution tai1,
trip_location tail1,
trip_rank tr1
ON
tp.id = ta1.publication_id
AND tp1.id = ta1.person_id
AND ta1.order = 1
AND tai1.id = ta1.institution_id
AND tail1.id = tai1.location_id
AND ta1.rank_id = tr1.id
The query seems to be dying on the "trip_author ta1" line, where I marked it above. The actual error message is:
syntax error at or near ","
LINE 77: (trip_author ta1, trip_person tp1, ...
I went through the docs, and it seems to be correct. What exactly am I doing wrong here? Any feedback would be much appreciated.
I don't know postgres, but in regular SQL you would need to a series of LEFT JOIN statements rather than your comma syntax. You seemed to have started this then stopped after the first two.
Something like:
SELECT * FROM
table1
LEFT JOIN table2 ON match1
LEFT JOIN table3 ON match2
WHERE otherFilters
The alternative is the older SQL syntax of:
SELECT cols
FROM table1, table2, table3
WHERE match AND match2 AND otherFilters
There's a couple of other smaller errors in your SQL, like the fact you forgot your tp alias on your first table, and have tried including a where clause (ta1.order = 1) as a joining constraint.
I think this is what you are after:
select (tons of stuff)
from trip_publication tp
left join trip_collection AS "tc" on tc.id = tp.collection_id
left join trip_author ta1 on ta1.publication_id = tp.id
left join trip_person tp1 on tp1.id = ta1.person_id
left join trip_institution tai1 on tai1.id = ta1.institution_id
left join trip_location tail1 on tail1.id = tai1.location_id
left join trip_rank tr1 on tr1.id = ta1.rank_id
where ta1.order = 1
Your left joins are one per table you are joining
left join trip_author ta1 on ....
left join trip_person tp1 on ....
left join trip_institution on ...
...and so on

Using left join and inner join in the same query

Below is my query using a left join that works as expected. What I want to do is add another table filter this query ever further but having trouble doing so. I will call this new table table_3 and want to add where table_3.rwykey = runways_updatable.rwykey. Any help would be very much appreciated.
SELECT *
FROM RUNWAYS_UPDATABLE
LEFT JOIN TURN_UPDATABLE
ON RUNWAYS_UPDATABLE.RWYKEY = TURN_UPDATABLE.RWYKEY
WHERE RUNWAYS_UPDATABLE.ICAO = 'ICAO'
AND (RUNWAYS_UPDATABLE.TORA > 4000 OR LDA > 0)
AND (TURN_UPDATABLE.AIRLINE_CODE IS NULL OR TURN_UPDATABLE.AIRLINE_CODE = ''
OR TURN_UPDATABLE.AIRLINE_CODE = '')
'*************EDIT To CLARIFY *****************
Here is the other statement that inner join i would like to use and I would like to combine these 2 statements.
SELECT *
FROM RUNWAYS_UPDATABLE A, RUNWAYS_TABLE B
WHERE A.RWYKEY = B.RWYKEY
'***What I have so far as advice taken below, but getting syntax error
SELECT RUNWAYS_UPDATABLE.*, TURN_UPDATABLE.*, AIRPORT_RUNWAYS_SELECTED.*
FROM RUNWAYS_UPDATABLE
INNER JOIN AIRPORT_RUNWAYS_SELECTED
ON RUNWAYS_UPDATABLE.RWYKEY = AIRPORT_RUNWAYS_SELECTED.RWYKEY
LEFT JOIN TURN_UPDATABLE
ON RUNWAYS_UPDATABLE.RWYKEY = TURN_UPDATABLE.RWYKEY
NOTE: If i comment out the inner join and leave the left join or vice versa, it works but when I have both of joins in the query, thats when im getting the syntax error.
I always come across this question when searching for how to make LEFT JOIN depend on a further INNER JOIN. Here is an example for what I am searching when I am searching for "using LEFT JOIN and INNER JOIN in the same query":
SELECT *
FROM foo f1
LEFT JOIN (bar b1
INNER JOIN baz b2 ON b2.id = b1.baz_id
) ON
b1.id = f1.bar_id
In this example, b1 will only be included if b2 is also found.
Remember that filtering a right-side table in left join should be done in join itself.
select *
from table1
left join table2
on table1.FK_table2 = table2.id
and table2.class = 'HIGH'
I finally figured it out. Thanks for all your help!!!
SELECT * FROM
(AIRPORT_RUNWAYS_SELECTED
INNER JOIN RUNWAYS_UPDATABLE
ON AIRPORT_RUNWAYS_SELECTED.RWYKEY = RUNWAYS_UPDATABLE.RWYKEY)
LEFT JOIN TURN_UPDATABLE ON RUNWAYS_UPDATABLE.RWYKEY = TURN_UPDATABLE.RWYKEY
Add your INNER_JOIN before your LEFT JOIN:
SELECT *
FROM runways_updatable ru
INNER JOIN table_3 t3 ON ru.rwykey = t3.rwykey
LEFT JOIN turn_updatable tu
ON ru.rwykey = tu.rwykey
AND (tu.airline_code IS NULL OR tu.airline_code = '' OR tu.airline_code = '')
WHERE ru.icao = 'ICAO'
AND (ru.tora > 4000 OR ru.lda > 0)
If you LEFT JOIN before your INNER JOIN, then you will not get results from table_3 if there is no matching row in turn_updatable. It's possible this is what you want, but since your join condition for table_3 only references runways_updatable, I would assume that you want a result from table_3, even if there isn't a matching row in turn_updatable.
EDIT:
As #NikolaMarkovinović pointed out, you should filter your LEFT JOIN in the join condition itself, as you see above. Otherwise, you will not get results from the left-side table (runways_updatable) if that condition isn't met in the right-side table (turn_updatable).
EDIT 2: OP mentioned this is actually Access, and not MySQL
In Access, perhaps it's a difference in the table aliases. Try this instead:
SELECT [ru].*, [tu].*, [ars].*
FROM [runways_updatable] AS [ru]
INNER JOIN [airport_runways_selected] AS [ars] ON [ru].rwykey = [ars].rwykey
LEFT JOIN [turn_updatable] AS [tu]
ON [ru].rwykey = [tu].rwykey
AND ([tu].airline_code IS NULL OR [tu].airline_code = '' OR [tu].airline_code = '')
WHERE [ru].icao = 'ICAO'
AND ([ru].tora > 4000 OR [ru].lda > 0)
If it is just an inner join that you want to add, then do this. You can add as many joins as you want in the same query. Please update your answer if this is not what you want, though
SELECT *
FROM RUNWAYS_UPDATABLE
LEFT JOIN TURN_UPDATABLE
ON RUNWAYS_UPDATABLE.RWYKEY = TURN_UPDATABLE.RWYKEY
INNER JOIN table_3
ON table_3.rwykey = runways_updatable.rwykey
WHERE RUNWAYS_UPDATABLE.ICAO = 'ICAO'
AND (RUNWAYS_UPDATABLE.TORA > 4000 OR LDA > 0)
AND (TURN_UPDATABLE.AIRLINE_CODE IS NULL OR TURN_UPDATABLE.AIRLINE_CODE = ''
OR TURN_UPDATABLE.AIRLINE_CODE = '')
I am not really sure what you want. But maybe something like this:
SELECT RUNWAYS_UPDATABLE.*, TURN_UPDATABLE.*
FROM RUNWAYS_UPDATABLE
JOIN table_3
ON table_3.rwykey = runways_updatable.rwykey
LEFT JOIN TURN_UPDATABLE
ON RUNWAYS_UPDATABLE.RWYKEY = TURN_UPDATABLE.RWYKEY
WHERE RUNWAYS_UPDATABLE.ICAO = 'ICAO'
AND (RUNWAYS_UPDATABLE.TORA > 4000 OR LDA > 0)
AND (TURN_UPDATABLE.AIRLINE_CODE IS NULL OR TURN_UPDATABLE.AIRLINE_CODE = ''
OR TURN_UPDATABLE.AIRLINE_CODE = '')
For Postgres, query planner does not guarantee order of execution of join. To Guarantee one can use #Gajus solution but the problem arises if there are Where condition for inner join table's column(s). Either one would to require to carefully add the where clauses in the respective Join condition or otherwise it is better to use subquery the inner join part, and left join the output.