I'm trying to create a custom column which is the multiplication of 2 existing columns.
(
select
omdDeliveryQty * omlUnitPriceBase AS 'Value'
) *
from
SalesOrderDeliveries
Left Outer Join SALESORDERLINES On OMDSALESORDERID = OMLSALESORDERID
And OMDSALESORDERLINEID = OMLSALESORDERLINEID
You probably want:
select
*,
d.omdDeliveryQty * l.omlUnitPriceBase AS 'Value'
from SalesOrderDeliveries d
left outer join SALESORDERLINES l
on d.OMDSALESORDERID = l.OMLSALESORDERID
and d.OMDSALESORDERLINEID = l.OMLSALESORDERLINEID
Don't forget to add aliases to each table (I added d and l) to make the query eaier to read and to debug.
Related
Why am i getting an error saying that SA2_NAME_2016 is not found when that column is indeed in table c?
select a.Avg__O_Sample_A_5G, a.Avg__O_Sample_A_All_5G, a.Avg__O_Sample_iOS_5G, a.Avg__O_Sample_iOS_All_5G,b.*, c.geomtry
from o-a-c-prd.R_A_K_SCORE_BREAKDOWN.Churn_May as a
left join
(select * from o-a-c-prd.R_A_K_SCORE_BREAKDOWN.A_K_MAY where Month = '2022-05') as b
on
a.SA2 = b.SA2_NAME_2016
JOIN
(select geometry from o-a-c-prd.R_P_Polygons.SA2_GEO_PUB_T ) as c
on
a.SA2 = c.SA2_NAME_2016
The ONLY column available in c is geometry!! So, the error you see makes total sense
Use below instead
select a.Avg__O_Sample_A_5G,
a.Avg__O_Sample_A_All_5G,
a.Avg__O_Sample_iOS_5G,
a.Avg__O_Sample_iOS_All_5G,
b.*,
c.geometry
from o-a-c-prd.R_A_K_SCORE_BREAKDOWN.Churn_May as a
left join
(select * from o-a-c-prd.R_A_K_SCORE_BREAKDOWN.A_K_MAY where Month = '2022-05') as b
on a.SA2 = b.SA2_NAME_2016
JOIN
(select SA2_NAME_2016, geometry from o-a-c-prd.R_P_Polygons.SA2_GEO_PUB_T ) as c
on a.SA2 = c.SA2_NAME_2016
Regarding the statement below, sltrxid can exist as both ardoccrid and ardocdbid. I'm wanting to know how to include both in the NOT IN subquery.
SELECT *
FROM glsltransaction A
INNER JOIN cocustomer B ON A.acctid = B.customerid
WHERE sltrxstate = 4
AND araccttype = 1
AND sltrxid NOT IN(
SELECT ardoccrid,ardocdbid
FROM arapplyitem)
I would recommend not exists:
SELECT *
FROM glsltransaction t
INNER JOIN cocustomer c ON c.customerid = t.acctid
WHERE
??.sltrxstate = 4
AND ??.araccttype = 1
AND NOT EXISTS (
SELECT 1
FROM arapplyitem a
WHERE ??.sltrxid IN (a.ardoccrid, a.ardocdbid)
)
Note that I changed the table aliases to things that are more meaningful. I would strongly recommend prefixing the column names with the table they belong to, so the query is unambiguous - in absence of any indication, I represented this as ?? in the query.
IN sometimes optimize poorly. There are situations where two subqueries are more efficient:
SELECT *
FROM glsltransaction t
INNER JOIN cocustomer c ON c.customerid = t.acctid
WHERE
??.sltrxstate = 4
AND ??.araccttype = 1
AND NOT EXISTS (
SELECT 1
FROM arapplyitem a
WHERE ??.sltrxid = a.ardoccrid
)
AND NOT EXISTS (
SELECT 1
FROM arapplyitem a
WHERE ??.sltrxid = a.ardocdbid
)
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?)
When I try something like the following:
SELECT *
FROM Abc
JOIN Def ON Abc.Id = Def.Id
JOIN Ghi ON Def.Id = Ghi.Id
LEFT JOIN (
SELECT Result = dbo.SomeBooleanFunction(Abc.Id)
)
Func ON Func.Result = 1
I get an error message of: The multi-part identifier "Abc.Id" could not be bound.
What is the appropriate way to join to the result of a function when it requires a parameter from the joins outside it?
It sounds like you actually want this.
SELECT *
FROM (
SELECT *
, dbo.SomeBooleanFunction(Abc.Id) [Result]
FROM Abc
JOIN Def ON Abc.Id = Def.Id
JOIN Ghi ON Def.Id = Ghi.Id
)a
WHERE a.Result=1
OR
SELECT *
FROM Abc
JOIN Def ON Abc.Id = Def.Id
JOIN Ghi ON Def.Id = Ghi.Id
WHERE dbo.SomeBooleanFunction(Abc.Id)=1
Unfortunately, the join source cannot reference outer columns. I do not know the reason for this. Reformulate the query using OUTER APPLY which is just like a LEFT JOIN but it can reference outer columns.
OUTER APPLY (
SELECT * FROM (SELECT Result = dbo.SomeBooleanFunction(Abc.Id)) x
WHERE Result = 1
) Func
You said:
I can't possibly keep wrapping for each function result that I have to filter by.
You could do this:
SELECT *
FROM MyTablesAndJoinsHere
CROSS APPLY (
SELECT
Result1 = dbo.MyFunc1(...)
, Result2 = dbo.MyFunc2(...)
, Result3 = dbo.MyFunc3(...)
) funcResults
You can easily add additional function-generated columns this way and select and filter on them easily.
I have the following query which returns the desired data. What I want to do is delete that data, however when I change the Select DQ.* to DELETE FROM DQ, I get an error indicating that
'... not updatable because the modification affects multiple base table'
I need to delete entries from the tbaccess_groupPermission table where appropriate module records are not found in the tbaccess_companyModules table.
WITH DQ AS
(
SELECT GP.* FROM tbaccess_groupPermission GP
JOIN tbaccess_groups G ON GP.GroupID = G.ID
WHERE G.CompanyID=6
AND GP.RoleName NOT IN
(
select Distinct(R.RoleName)
FROM tbAccess_Roles R
INNER JOIN tbAccess_CompanyModules C on R.ModuleID = C.ModuleID
WHERE C.CompanyID = 6)
)
SELECT * FROM DQ
Why not change the WITH statement to use an IN clause?
Something like
WITH DQ AS
(
SELECT GP.* FROM tbaccess_groupPermission GP
WHERE GP.GroupID IN (SELECT G.ID FROM tbaccess_groups G WHERE G.CompanyID=6)
AND GP.RoleName NOT IN
(
select Distinct(R.RoleName)
FROM tbAccess_Roles R
INNER JOIN tbAccess_CompanyModules C on R.ModuleID = C.ModuleID
WHERE C.CompanyID = 6)
)