Joining results of two queries: #1248 - Every derived table must have its own alias - sql

I'm trying to combine the results produced by two queries on my database...
q1:
SELECT * FROM werkgevers JOIN werkgevers_branches ON werkgevers.werkgever_id = werkgevers_branches.werkgever_id JOIN plaatsen ON werkgevers.plaats_id = plaatsen.plaats_id JOIN branches ON werkgevers_branches.branche_id = branches.branche_id GROUP BY werkgevers_branches.werkgever_id
q2:
SELECT werkgever_id, COUNT(werkgever_id) AS aantalvacatures FROM vacatures GROUP BY werkgever_id
... like this:
SELECT * FROM (
SELECT * FROM werkgevers JOIN werkgevers_branches ON werkgevers.werkgever_id = werkgevers_branches.werkgever_id JOIN plaatsen ON werkgevers.plaats_id = plaatsen.plaats_id JOIN branches ON werkgevers_branches.branche_id = branches.branche_id GROUP BY werkgevers_branches.werkgever_id
) AS tbl1
LEFT OUTER JOIN
(
SELECT * FROM (
SELECT werkgever_id, COUNT(werkgever_id) AS aantalvacatures FROM vacatures GROUP BY werkgever_id
) AS tbl2
)
USING (werkgever_id)
but I keep getting the error
#1248 - Every derived table must have its own alias
I'm not sure where I should name any derived tables, any suggestions?

Your LEFT OUTER JOIN derived table needs an alias. Try this:
select *
from (
select *
from werkgevers
join werkgevers_branches on werkgevers.werkgever_id = werkgevers_branches.werkgever_id
join plaatsen on werkgevers.plaats_id = plaatsen.plaats_id
join branches on werkgevers_branches.branche_id = branches.branche_id
group by werkgevers_branches.werkgever_id
) as tbl1
left outer join (
select *
from (
select werkgever_id,
COUNT(werkgever_id) as aantalvacatures
from vacatures
group by werkgever_id
) as tbl2
) a USING (werkgever_id)
Note the alias a on the last line.

Related

LEFT JOIN & SUM GROUP BY

EDIT:
The result supposed to be like this:
desired result
I have this query:
SELECT DISTINCT mitarbeiter.mitarbnr, mitarbeiter.login, mitarbeiter.name1, mitarbeiter.name2
FROM vertragspos
left join vertrag_ek_vk_zuord ON vertragspos.id = vertrag_ek_vk_zuord.ek_vertragspos_id
left join mitarbeiter ON vertrag_ek_vk_zuord.anlage_mitarbnr = mitarbeiter.mitarbnr
left join vertragskopf ON vertragskopf.id = vertragspos.vertrag_id
left join
(
SELECT wkurse.*, fremdwaehrung.wsymbol
FROM wkurse
INNER join
(
SELECT lfdnr, Max(tag) AS maxTag
FROM wkurse
WHERE tag < SYSDATE
GROUP BY lfdnr
) t1
ON wkurse.lfdnr = t1.lfdnr AND wkurse.Tag = t1.maxTag
INNER JOIN fremdwaehrung ON wkurse.lfdnr = fremdwaehrung.lfdnr
) wkurse ON vertragskopf.blfdwaehrung = wkurse.lfdnr
left join
(
SELECT vertrag_ID, Sum (preis) preis, Sum (menge) menge, Sum (preis * menge / Decode (vertragskopf.zahlintervall, 1,1,2,2,3,3,4,6,5,12,1) / wkurse.kurs) vertragswert
FROM vertragspos
GROUP BY vertrag_ID
) s ON vertragskopf.id = s.vertrag_id
But I always get an error on line 21 Pos 145:
ORA-00904 WKURSE.KURS invalid identifier
The WKURSE table is supposed be joined already above, but why do I still get error?
How can I do join with all these tables?
I need to join all these tables:
Mitarbeiter, Vertragspos, vertrag_ek_vk_zuord, wkurse, fremdwaehrung, vertragskopf.
What is the right syntax? I'm using SQL Tool 1,8 b38
Thank you.
Because LEFT JOIN is executed on entire dataset, and not in row-by-row manner. So there's no wkurse.kurs available in the execution context of subquery. Since you join that tables, you can place the calculation in the top-most select statement.
EDIT:
After you edited the statement, it became clear where does vertragskopf.zahlintervall came from. But I don't know where are you going to use calculated vertragswert (now it is absent in the query), so I've put it in the result. As I'm not a SQL parser and have no idea of your tables, so I cannot check the code, but calculation now can be resolved (all the values are available in calculation context).
SELECT DISTINCT mitarbeiter.mitarbnr, mitarbeiter.login, mitarbeiter.name1, mitarbeiter.name2, s.amount / Decode (vertragskopf.zahlintervall, 1,1,2,2,3,3,4,6,5,12,1) / wkurse.kurs) vertragswert
FROM vertragspos
left join vertrag_ek_vk_zuord ON vertragspos.id = vertrag_ek_vk_zuord.ek_vertragspos_id
left join mitarbeiter ON vertrag_ek_vk_zuord.anlage_mitarbnr = mitarbeiter.mitarbnr
left join vertragskopf ON vertragskopf.id = vertragspos.vertrag_id
left join (
SELECT wkurse.*, fremdwaehrung.wsymbol
FROM wkurse
INNER join (
SELECT lfdnr, Max(tag) AS maxTag
FROM wkurse
WHERE tag < SYSDATE
GROUP BY lfdnr
) t1
ON wkurse.lfdnr = t1.lfdnr AND wkurse.Tag = t1.maxTag
INNER JOIN fremdwaehrung ON wkurse.lfdnr = fremdwaehrung.lfdnr
) wkurse ON vertragskopf.blfdwaehrung = wkurse.lfdnr
left join (
SELECT vertrag_ID, Sum (preis) preis, Sum (menge) menge, Sum (preis * menge) as amount
FROM vertragspos
GROUP BY vertrag_ID
) s ON vertragskopf.id = s.vertrag_id
Rewriting the code using WITH clause makes it much clearer than select from select.
Also get the rate on last day before today in oracle is as simple as
select wkurse.lfdnr
, max(wkurse.kurs) keep (dense_rank first order by wkurse.tag desc) as rate
from wkurse
where tag < sysdate
group by wkurse.lfdnr
One option is a lateral join:
left join lateral
(SELECT vertrag_ID, Sum(preis) as preis, Sum(menge) as menge,
Sum (preis * menge / Decode (vertragskopf.zahlintervall, 1,1,2,2,3,3,4,6,5,12,1) / wkurse.kurs) vertragswert
FROM vertragspos
GROUP BY vertrag_ID
) s
ON vertragskopf.id = s.vertrag_id

PostgreSQL how to use with as

Anybody know why this isn't working? I'm getting: ERROR: syntax error at or near "most_recent"
with most_recent as (SELECT MAX(public."Master_playlist".updated_at)
FROM public."Master_playlist")
SELECT * from public."Playlist"
JOIN public."Master_playlist_playlist" on public."Playlist".id = public."Master_playlist_playlist".playlist_id
JOIN public."Master_playlist" on public."Master_playlist_playlist".master_playlist_id = public."Master_playlist".id
WHERE public."Master_playlist".updated_at = most_recent;
Supposed to be getting the most recent date from Master_playlist and then using that to select a Master_playlist to join the inner query with
Thanks! HM
The with clause creates a derived table, which you need select from, using a join or a subquery. You also need to alias the column so you can refer to it afterwards, as in:
with most_recent as (
SELECT MAX(updated_at) max_updated_at
FROM public."Master_playlist"
)
SELECT *
from public."Playlist"
JOIN public."Master_playlist_playlist"
on public."Playlist".id = public."Master_playlist_playlist".playlist_id
JOIN public."Master_playlist"
on public."Master_playlist_playlist".master_playlist_id = public."Master_playlist".id
WHERE public."Master_playlist".updated_at = (SELECT max_updated_at FROM most_recent)
But here, it looks like it is simpler to use a row-limiting query:
select ...
from (
select *
from public."Master_playlist"
order by updated_at desc
limit 1
) mp
inner join public."Master_playlist_playlist" mpp
on mpp.master_playlist_id = mp.id
inner join public."Playlist" p
on p.id = mpp.playlist_id

SQL Selecting rows with not the same condition for all

I have to create SQL query that select persons datas. Every person has several grades and I have to select first by time for everyone. I don't know how do it because conditional is different for every person. Below is my current code which doesn't works.
SELECT s.sol_last_name,
g.grade_name,
MIN(sg.sol_grade_date_from)
FROM [dbo].[dim_s####] AS s
LEFT JOIN [dbo].[fact_s####_grade] AS sg ON s.sol_key = sg.sol_grade_sollers_key
LEFT JOIN [dbo].[dim_grade] AS g ON g.grade_key = sg.sol_grade_grade_key
GROUP BY s.sol_last_name,
g.grade_name
HAVING MIN(sg.sol_grade_date_from) = sg.sol_grade_date_from
You can put the earliest date in a subquery, and then inner join there:
SELECT s.sol_last_name,
g.grade_name,
sg.sol_grade_date_from
FROM [dbo].[dim_s####] AS s
INNER JOIN (
select sol_grade_grade_key
,min(sol_grade_date_from) as sol_grade_date_
from from [dbo].[dim_grade]
GROUP BY sol_grade_grade_key) AS g
ON g.grade_key = sg.sol_grade_grade_key
LEFT JOIN [dbo].[fact_s####_grade] AS sg
ON s.sol_key = sg.sol_grade_sollers_key
Use a Common Table Expression (cte) to save some typing. Then do a NOT EXISTS to return a row only if same sol_last_name has no older grade.
WITH CTE (sol_last_name, grade_name, grade_date_from) AS
(
SELECT s.sol_last_name,
g.grade_name,
sg.sol_grade_date_from
FROM [dbo].[dim_s####] AS s
LEFT JOIN [dbo].[fact_s####_grade] AS sg ON s.sol_key = sg.sol_grade_sollers_key
LEFT JOIN [dbo].[dim_grade] AS g ON g.grade_key = sg.sol_grade_grade_key
)
select sol_last_name, grade_name, grade_date_from
from cte as t1
where not exists (select 1 from cte t2
where t2.sol_last_name = t1.sol_last_name
and t2.grade_date_from < t2.grade_date_from)

Nested SQL - Distinct Load Left Join in one statement

I wanted to left join two queries:
First:
SELECT TIG_TOL.sName AS Maschine,
TIG_TOL.lTolRef,
Max(TIG_JOB.tActBegin) AS MaxvontActBegin
FROM TIG_JOB LEFT JOIN TIG_TOL ON TIG_JOB.lMacRef = TIG_TOL.lTolRef
WHERE (((TIG_JOB.sState)="Run" Or (TIG_JOB.sState)="Ready"))
GROUP BY TIG_TOL.sName, TIG_TOL.lTolRef;
Second:
SELECT TIG_JOB.sName AS Auftrag,
TIG_JOB.lJobRef,
TIG_TOL.sName AS Artikel,
TIG_TOL.sDescript AS Artikel_Bezeichnung
FROM (TIG_JOB LEFT JOIN TIG_TOL_BOK ON TIG_JOB.lJobRef = TIG_TOL_BOK.lJobRef)
LEFT JOIN TIG_TOL ON (TIG_TOL_BOK.lTolRef = TIG_TOL.lTolRef)
AND (TIG_TOL_BOK.lTolTypRef = TIG_TOL.lTolTypRef)
WHERE (((TIG_TOL.lTolTypRef)=10));
Over a left join
on First.MaxvontActBegin = Second.TIG_JOB.tActBegin
AND First.TIG_TOL.lTolRef = Second.TIG_JOB.lMacRef
Is that possible? In Access Im doing it over two queries, where the second is using the first..
I (blindly) added TIG_JOB.tActBegin and TIG_JOB.lMacRef to the 2nd SELECT (hoping they exist) in order to JOIN the two results.
I used SELECT * only because you did not specify the column selection.
SELECT *
FROM
(
SELECT TIG_TOL.sName AS Maschine,
TIG_TOL.lTolRef,
Max(TIG_JOB.tActBegin) AS MaxvontActBegin
FROM TIG_JOB LEFT JOIN TIG_TOL ON TIG_JOB.lMacRef = TIG_TOL.lTolRef
WHERE (((TIG_JOB.sState)="Run" Or (TIG_JOB.sState)="Ready"))
GROUP BY TIG_TOL.sName, TIG_TOL.lTolRef
) AS FirstTable
LEFT JOIN
(
SELECT TIG_JOB.sName AS Auftrag,
TIG_JOB.lJobRef,
TIG_TOL.sName AS Artikel,
TIG_TOL.sDescript AS Artikel_Bezeichnung,
TIG_JOB.tActBegin,
TIG_JOB.lMacRef
FROM (TIG_JOB LEFT JOIN TIG_TOL_BOK ON TIG_JOB.lJobRef = TIG_TOL_BOK.lJobRef)
LEFT JOIN TIG_TOL ON (TIG_TOL_BOK.lTolRef = TIG_TOL.lTolRef)
AND (TIG_TOL_BOK.lTolTypRef = TIG_TOL.lTolTypRef)
WHERE (((TIG_TOL.lTolTypRef)=10))
) AS SecondTable
ON FirstTable.MaxvontActBegin = SecondTable.tActBegin
AND FirstTable.lTolRef = SecondTable.lMacRef`

Error message - Every derived table must have its own alias

I have this SQL Syntax but it's not working and receive this error:
"#1248 - Every derived table must have its own alias".
Could you help me?
SELECT *
FROM produse_comenzi
JOIN comenzi ON comenzi.id_comanda = produse_comenzi.id_comanda
JOIN (SELECT DISTINCT numar_factura FROM facturi)
ON facturi.id_comanda = comenzi.id_comanda
In the second join you are using a subquery but you haven't given the result an alias, i.e. something to identify the result by
SELECT *
FROM produse_comenzi
JOIN comenzi
ON comenzi.id_comanda = produse_comenzi.id_comanda
JOIN (SELECT DISTINCT numar_factura FROM facturi) -- has no alias
ON facturi.id_comanda = comenzi.id_comanda
you should do
SELECT *
FROM produse_comenzi
JOIN comenzi
ON comenzi.id_comanda = produse_comenzi.id_comanda
JOIN (SELECT DISTINCT numar_factura, id_comanda FROM facturi) AS facturi
ON facturi.id_comanda = comenzi.id_comanda
You must add an alias to each subquery that's being treated as a table:
SELECT *
FROM produse_comenzi
JOIN comenzi ON comenzi.id_comanda = produse_comenzi.id_comanda
JOIN (SELECT DISTINCT numar_factura FROM facturi) x
ON x.id_comanda = comenzi.id_comanda
Here I have named the result set x and referred to that in the join condition. You can change "x" to whatever you like.
This should fix it:
(there is a need in SQL to distinguish between different Resultset from selects)
SELECT *
FROM produse_comenzi AS table_1
JOIN comenzi AS table_2
ON table_2.id_comanda = table_1.id_comanda
JOIN (SELECT DISTINCT numar_factura FROM facturi AS table_3)
ON table_3.id_comanda = table_2.id_comanda