I'm working on this SELECT query:
SELECT * FROM x
JOIN y ON x.struktorg = y.ref
WHERE y.rodzic = (SELECT ref FROM y WHERE y.symbol = 'the value i know')
The goal is to not use subselect. I know the value of symbol column, but the table that I need to get results from doesn't use it. It uses the reference number of that value.
you can join to y one more time:
SELECT * FROM x
JOIN y y1 ON x.struktorg = y1.ref
join y y2
ON y1.rodzic = y2.ref
and y2.symbol = 'the value i know'
but I don't see any benefit using join over subquery in this scenario .
if the subquery table y is the same of the JOIN y, then you can do this
SELECT *
FROM x
JOIN y ON x.struktorg = y.ref and y.rodzic = y.ref and y.symbol = 'the value i know'
if the subquery table y is diferent of the JOIN y, then you can do this renaming subquery table y for z
SELECT * FROM x
JOIN y ON x.struktorg = y.ref
JOIN z ON y.rodzic = z.ref and z.symbol = 'the value i know'
I would go around the sub-select by creating a temporary table first, like in the example below:
SELECT ref INTO #TEMP_TABLE FROM y WHERE y.symbol = 'the value i know'
Then I would join on that temporary table I created like in the example here:
SELECT * FROM x
JOIN y ON x.struktorg = y.ref
JOIN #TEMP_TABLE z on z.ref = y.rodzic
Having said that, I am sure that the above solution works effectively for SQL Server. However, I've never used Firebird, so the principles there might be different.
Related
I have the following pseudo-sqlite call:
SELECT x, y,
(SELECT --very long SQL call--) AS z,
(SELECT a FROM diff_table_name WHERE b = z) AS e
FROM table_name
WHERE c = d
Essentially I want to use the z variable result from the first subquery in the second subquery, but I get a
no such column: z
error when I do. I can repeat the very long SQL call in the second subquery and that works, but I was hoping to not have to do that. Or maybe there's a way to return both a and z from one subquery?
This part of your query:
SELECT x, y,
(SELECT --very long SQL call--) AS z
FROM table_name
WHERE c = d
can be safely wrapped inside a CTE and then use the value of z:
WITH cte AS (
SELECT x, y,
(SELECT --very long SQL call--) AS z
FROM table_name
WHERE c = d
)
SELECT x, y, z,
(SELECT a FROM diff_table_name WHERE b = z) AS e
FROM cte
Is it possible to write multiple queries inside the SQL EXISTS()?
Just as this example
SELECT
EXISTS (SELECT a FROM at WHERE X = :X;
SELECT b FROM bt WHERE Y = :Y;
SELECT C FROM ct WHERE Z = :Z;
)
And in case it is possible, is this the best way to check the existence of an element inside multiple tables? or using UNION ALL or JOIN would be better?
Use OR:
EXISTS (SELECT a FROM at WHERE X = :X) OR
EXISTS (SELECT b FROM bt WHERE Y = :Y) OR
EXISTS (SELECT C FROM ct WHERE Z = :Z)
This would normally be in a WHERE or CASE, not a SELECT.
You can use UNION ALL, but this is usually more efficient.
I have two tables X and Y:
X has columns ID (primary key), Name
Y has a foreign key to X referencing the ID column
I can only get the Name value from an input.
I need to get all rows in Y which match the Name as found in X
How do I write this SQL query?
I have been through a few tutorial by I am unable to understand how to achieve this. Any help would be great.
Thank you
Select *
from y
left join x on x.id = y.xid
where x.name = #nameparameter
A query like above should do the job. I can explain further if you will
If you just need the attributes of 'y', use
select y.* from y join x on y.x = x.id where x.name = 'your desired name'.
SELECT Y.[Id], Y.[Name]
FROM [dbo].[Y]
INNER JOIN [dbo].[X] ON [Y].ForeignKeyId = X.Id
WHERE X.Name LIKE '%YOUR_Query%'
I've these two approaches for a problem and they look kind of okay to me. Is there a better way to do this? Please advise.
X,Y,Z are same for both queries
Two queries and add the values:
select sum(columnA1), sum(columnA2) from tableA
where columnA3 = X and columnA4 = Y and columnA5 = Z;
select sum(columnB1) from tableB
where columnB3 = X and columnB4 = Y and columnB5 = Z;
Union All:
select sum(columnA1), sum(columnA2), sum(columbB1)
from (select columnA1, columnA2, null from tableA
where columnA3 = X and columnA4 = Y and columnA5 = Z
union all
select null, null, columnB1 from tableB
where columnB3 = X and columnB4 = Y and columnB5 = Z) unionresult
Each of your 2 options will produce the same 3 numeric results, the only real difference is in the delivery (either as 2 queries or as a single, combined, query).
I cannot really know which suits your purpose best, but you are adding a tiny overhead to get get a combined result.
Here is another possible alternative for a combined result but I don't think it's any better than the union all approach you show (& it could even be worse).
SELECT
SUM(columnA1)
, SUM(columnA2)
, (
SELECT
SUM(columnB1)
FROM tableB
WHERE columnB3 = X
AND columnB4 = Y
AND columnB5 = Z
) as sum_columnB1
FROM tableA
WHERE columnA3 = X
AND columnA4 = Y
AND columnA5 = Z
;
The following query works fine. It is a series of nested joins to give me a kind of master table:
SELECT *
FROM proj_trainer k
JOIN
(
SELECT *
FROM proj_breeder i
JOIN
(
SELECT *
FROM proj_jockey g
JOIN
(
SELECT *
FROM proj_horses e
JOIN
(
SELECT *
FROM proj_results c
JOIN
(
SELECT *
FROM proj_race_details a
JOIN proj_meet b
ON a.meet_id = b.meet_id
) d
ON c.race_id = d.race_id
) f
ON e.horse_id = f.horse_id
) h
ON g.jockey_id = h.jockey_id
)j
ON i.breeder_id = j.breeder_id
) l
ON k.trainer_id = l.trainer_id;
This works fine with one odd feature, which isn't my main problem. Some of the columns are return with strange codes such as "QCSJ_C000000001300001". Not sure why, or if this relates to my actual problem.
The real problem is that when I add just one more join sub-query I get:
ORA-00904: "N"."RACE_ID": invalid identifier
Here's the same code with the extra nested block (the one on the very outside)
SELECT *
FROM proj_entry m
JOIN
(
SELECT *
FROM proj_trainer k
JOIN
(
SELECT *
FROM proj_breeder i
JOIN
(
SELECT *
FROM proj_jockey g
JOIN
(
SELECT *
FROM proj_horses e
JOIN
(
SELECT *
FROM proj_results c
JOIN
(
SELECT *
FROM proj_race_details a
JOIN proj_meet b
ON a.meet_id = b.meet_id
) d
ON c.race_id = d.race_id
) f
ON e.horse_id = f.horse_id
) h
ON g.jockey_id = h.jockey_id
)j
ON i.breeder_id = j.breeder_id
) l
ON k.trainer_id = l.trainer_id
) n
ON n.race_id = m.race_id WHERE n.horse_id = m.horse_id;
I felt like I was well over the hill with this one and then the final line went wrong somehow, despite having virtually the same structure as all the previous blocks. I've also used the race_id and horse_id earlier in the code so they do work.
I've also tried this on the last line:
ON n.race_id = m.race_id AND n.horse_id = m.horse_id;
and a few other variations, with brackets etc....
At first I could't see anything wrong as such, but then I can't see anything terribly well with that syntax! The problem may be that "N"."RACE_ID" is ambiguous, since "N" is the alias for a query that joins many tables, perhaps more than one of which have a RACE_ID column?
Your SQL could be re-written as:
SELECT *
FROM proj_entry m
JOIN proj_trainer n ON n.race_id = m.race_id
JOIN proj_breeder l ON l.trainer_id = n.trainer_id
JOIN proj_jockey j ON j.breeder_id = l.breeder_id
JOIN proj_horses h ON h.jockey_id = j.jockey_id
JOIN proj_results f ON f.horse_id = h.horse_id
JOIN proj_race_details d ON d.race_id = f.race_id
JOIN proj_meet b ON b.meet_id = d.meet_id
WHERE n.horse_id = m.horse_id;
(But I could have made a mistake somewhere.)
That looks a lot simpler to me. It would be better still if the aliases were mnemonics for the actual table names rather than in most cases arbitrary letters of the alphabet:
SELECT *
FROM proj_entry e
JOIN proj_trainer t ON t.race_id = e.race_id
JOIN proj_breeder b ON b.trainer_id = n.trainer_id
JOIN proj_jockey j ON j.breeder_id = b.breeder_id
JOIN proj_horses h ON h.jockey_id = j.jockey_id
JOIN proj_results r ON r.horse_id = h.horse_id
JOIN proj_race_details d ON d.race_id = r.race_id
JOIN proj_meet m ON m.meet_id = d.meet_id
WHERE t.horse_id = e.horse_id;
You should then easily be able to check the joins to see that they are on the right columns. And now if you get an error like ORA-00904: "T"."RACE_ID": invalid identifier you will know for sure that it refers to table proj_trainer whereas previously "N"."RACE_ID" might be ambiguous since "N" was the alias of a query joining about half a dozen tables.
Also rather than SELECT * it might be better to specify the actual columns you want, which will avoid getting duplicates - for example:
SELECT e.race_id, t.trainer_id, t.trainer_name, ...
(I imagine the column names starting with 'QCSJ' that your query tool is generating are to cope with what would otherwise be duplicate column names in the results. What is the query tool?)