WHERE Clause does not accept just defined column - sql

This Code does not work:
SELECT
(
SELECT [T_Licence].[isInstalled]
FROM [T_Licence]
WHERE [T_Licence].[System] = [T_System].[ID]
AND [T_Licence].[Software] = 750
) AS [IsInstalled] ,*
FROM [T_System]
WHERE [IsInstalled] = 1
I have to do it this way, but this makes the whole code so complicated. I really dont want that:
SELECT
(
SELECT [T_Licence].[isInstalled]
FROM [wf_subj_all].[T_Licence]
WHERE [T_Licence].[System] = [T_System].[ID]
AND [T_Licence].[Software] = 750
) AS [IsInstalled] ,*
FROM [wf_subj_it].[T_System]
WHERE
(
SELECT
(
SELECT [T_Licence].[isInstalled]
FROM [wf_subj_all].[T_Licence]
WHERE [T_Licence].[System] = [T_System].[ID]
AND [T_Licence].[Software] = 750
)
) = 1
Is there any way to do it like shown in the first code snippet?
So that the code stays somehow readeble.
thx very much

Try this one -
SELECT *
FROM wf_subj_it.T_System s
CROSS APPLY (
SELECT /*TOP(1)*/ t.isInstalled
FROM wf_subj_all.T_Licence t
WHERE t.[System] = s.ID
AND t.Software = 750
) t
WHERE t.isInstalled = 1

Just wrap the query with an outer select and it should work.
SELECT *
FROM
(
SELECT
(
SELECT [T_Licence].[isInstalled]
FROM [T_Licence]
WHERE [T_Licence].[System] = [T_System].[ID]
AND [T_Licence].[Software] = 750
) AS [IsInstalled], *
FROM [T_System]
) As tbl1
WHERE [IsInstalled] = 1

The assumptions I made for my answer:
You're trying to select the systems (table T_System) which have software with id=750 installed
The table T_License contains the installed information
There is a 1:n relation between T_System and T_License: T_License may contain 0, 1 or more records per Sytem value...
but the combination System plus Software is unique
I think this will work
SELECT l.[isInstalled], s.*
FROM [wf_subj_it].[T_System] AS s
INNER JOIN [wf_subj_it].[T_License] AS l
ON l.[System] = s.[ID]
AND l.[Software] = 750
AND l.isInstalled = 1

Related

Optimize many subqueries with same source

Does anyone have any idea how to optimize such a query?
How do you encapsulate this into one query?
,(SELECT top 1 WFD_AttDecimal2 as Nocleg
FROM WFElements INNER JOIN
WFElementDetails ON WFElements.WFD_ID = WFElementDetails.DET_WFDID
Where
WFD_STPID = #KrokSlownikUdostepnionyKraj
and dbo.ClearWFElemID (WFD_AttChoose20) = KrajDoDiety6 -- id kraju
and dbo.ClearWFElemID (WFD_AttChoose9) = #Spolka) as NoclegStawka7
,(SELECT top 1 WFD_AttDecimal3 as NoclegPrzelicznik
FROM WFElements INNER JOIN
WFElementDetails ON WFElements.WFD_ID = WFElementDetails.DET_WFDID
Where
WFD_STPID = #KrokSlownikUdostepnionyKraj
and dbo.ClearWFElemID (WFD_AttChoose20) = KrajDoDiety6 -- id kraju
and dbo.ClearWFElemID (WFD_AttChoose9) = #Spolka) as NoclegPrzelicznik7
,PelneDoby6 * (select MinDieta from #MinDieta where RodzajDelegacji = KrajZagr6) as MinIloscDiet7
from #Dieta4
You can use OUTER APPLY or CROSS APPLY and select all the necessary columns within that, you can then access all of them in the SELECT
SELECT
wfd.Nocleg as NoclegStawka7
, wfd.NoclegPrzelicznik as NoclegPrzelicznik7
, d.PelneDoby6 * (select md.MinDieta from #MinDieta md where RodzajDelegacji = KrajZagr6) as MinIloscDiet7
from #Dieta4 d
OUTER APPLY (
SELECT TOP (1)
WFD_AttDecimal2 as Nocleg,
WFD_AttDecimal3 as NoclegPrzelicznik
FROM WFElements INNER JOIN
WFElementDetails ON WFElements.WFD_ID = WFElementDetails.DET_WFDID
Where
WFD_STPID = #KrokSlownikUdostepnionyKraj
and dbo.ClearWFElemID (WFD_AttChoose20) = KrajDoDiety6 -- id kraju
and dbo.ClearWFElemID (WFD_AttChoose9) = #Spolka
) wfd;
Note also:
I suggest you rethink your usage of a scalar function ClearWFElemID as it can be slow. Use a join or a Table Valued function instead.
TOP (1) without an ORDER BY is a code-smell: you may get a different result each time.
Always specify the table alias when using subqueries, or you risk getting the wrong results.

exists/not exists without referring to outer table

I am working on Activiti framework. This is a workflow automation framework in java. I have following query:
select RES.* from ACT_RU_TASK RES where exists
(select 1 from ACT_RU_IDENTITYLINK I where not exists
(
select 1 from ACT_RU_VARIABLE A0 where RES.ID_ = A0.TASK_ID_ and A0.NAME_= 'excludedUserForTask'
and A0.TYPE_ = 'string' and A0.TEXT_ ='my_id'
)
and I.TASK_ID_ = RES.ID_ and I.TYPE_ = 'candidate' and I.GROUP_ID_ IN ('my_skill_1')
)
and
RES.ASSIGNEE_ is null order by RES.priority_ desc ,RES.create_time_ LIMIT 10 OFFSET 0;
So, my objective is to fetch all the tasks(from table ACT_RU_TASK) which are not yet assigned(RES.ASSIGNEE_ is null), and which are not assignable to this user('my_id'), and need skill 'my_skill_1'. In activiti,ACT_RU_IDENTITYLINK table contains the link between a task and a skill(GROUP_ID_), and ACT_RU_VARIABLE contains information on variables associated to a task(here we ensure that variable 'excludedUserForTask' and 'my_id' are not paired).
But problem I face is that apart from tasks which need skill 'my_skill_1', I get other tasks too which need other skills.
Looking at the query, I am not sure about this part:
select 1 from ACT_RU_IDENTITYLINK I where not exists
(
select 1 from ACT_RU_VARIABLE A0 where RES.ID_ = A0.TASK_ID_ and A0.NAME_= 'excludedUserForTask'
and A0.TYPE_ = 'string' and A0.TEXT_ ='my_id'
)
and I.TASK_ID_ = RES.ID_ and I.TYPE_ = 'candidate' and I.GROUP_ID_ IN ('my_skill_1')
In subquery for NOT EXISTS, we are not referring to ACT_RU_IDENTITYLINK. Does exist/not exist work this way? I think we need to refer outer table(ACT_RU_IDENTITYLINK) too in subquery.
I believe that the not exists part has to be part of the outer query condition like this
select RES.*
from ACT_RU_TASK RES
where exists
(
select 1
from ACT_RU_IDENTITYLINK I
and I.TASK_ID_ = RES.ID_
and I.TYPE_ = 'candidate'
and I.GROUP_ID_ IN ('my_skill_1')
)
and not exists
(
select 1
from ACT_RU_VARIABLE A0
where RES.ID_ = A0.TASK_ID_
and A0.NAME_= 'excludedUserForTask'
and A0.TYPE_ = 'string' and A0.TEXT_ ='my_id'
)
and RES.ASSIGNEE_ is null
order by RES.priority_ desc ,RES.create_time_
LIMIT 10 OFFSET 0;

ORACLE SQL: Slow query when using "join table on id = id" vs "where id = number"

I'm having performance problem in a querie when I use a subquery to set an ID = number, and then join that subquery in the main query to look for that ID, this method takes about 150 seconds. But if I delete the subquery and look for the ID = number directly in the main query, it takes 0,5 second.
Here some code as exemple:
This is the example of 150 seconds
In this I set the cto_in_codigo in the With clause.
WITH CONTRATOS AS (
SELECT CTO_IN_CODIGO FROM MGCAR.CAR_CONTRATO
WHERE CTO_IN_CODIGO = 14393
)
SELECT
PT.PAR_IN_CODIGO,
PTC.PARCOR_IN_INDICE
FROM (
SELECT
MAX(PT.HPAR_IN_CODIGO) OVER (PARTITION BY PT.PAR_IN_CODIGO, PT.CTO_IN_CODIGO) HPAR_IN_CODIGO_MAX,
PT.HPAR_IN_CODIGO,
PT.CTO_IN_CODIGO,
PT.PAR_IN_CODIGO
FROM
QUERIE.PARCELA_TOTAL PT
JOIN CONTRATOS CTO
ON CTO.CTO_IN_CODIGO = PT.CTO_IN_CODIGO
WHERE
PT.PAR_DT_REAJUSTE <= TO_DATE('31/12/2017', 'DD/MM/YYYY')
) PT
LEFT OUTER JOIN (
SELECT
MAX(PTC.PARCOR_IN_CODIGO) OVER (PARTITION BY PTC.PAR_IN_CODIGO, PTC.CTO_IN_CODIGO) PARCOR_IN_CODIGO_MAX,
PTC.PARCOR_IN_CODIGO,
PTC.CTO_IN_CODIGO,
PTC.PAR_IN_CODIGO,
PTC.HPAR_IN_CODIGO,
PTC.PARCOR_IN_INDICE
FROM
QUERIE.PARCELA_TOTAL_CORRECAO PTC
JOIN CONTRATOS CTO
ON CTO.CTO_IN_CODIGO = PTC.CTO_IN_CODIGO
) PTC
ON PTC.CTO_IN_CODIGO = PT.CTO_IN_CODIGO
AND PTC.PAR_IN_CODIGO = PT.PAR_IN_CODIGO
AND PTC.HPAR_IN_CODIGO = PT.HPAR_IN_CODIGO
AND PTC.PARCOR_IN_CODIGO = PTC.PARCOR_IN_CODIGO_MAX
WHERE
PT.HPAR_IN_CODIGO = PT.HPAR_IN_CODIGO_MAX
and this is the 0,5 sec.
in this I set the cto_in_codigo inside each query
SELECT
PT.PAR_IN_CODIGO,
PTC.PARCOR_IN_INDICE
FROM (
SELECT
MAX(PT.HPAR_IN_CODIGO) OVER (PARTITION BY PT.PAR_IN_CODIGO, PT.CTO_IN_CODIGO) HPAR_IN_CODIGO_MAX,
PT.HPAR_IN_CODIGO,
PT.CTO_IN_CODIGO,
PT.PAR_IN_CODIGO
FROM
QUERIE.PARCELA_TOTAL PT
WHERE
PT.PAR_DT_REAJUSTE <= TO_DATE('31/12/2017', 'dd/MM/yyyy')
AND PT.CTO_IN_CODIGO = 14393
) PT
LEFT OUTER JOIN (
SELECT
MAX(PTC.PARCOR_IN_CODIGO) OVER (PARTITION BY PTC.PAR_IN_CODIGO, PTC.CTO_IN_CODIGO) PARCOR_IN_CODIGO_MAX,
PTC.PARCOR_IN_CODIGO,
PTC.CTO_IN_CODIGO,
PTC.PAR_IN_CODIGO,
PTC.HPAR_IN_CODIGO,
PTC.PARCOR_IN_INDICE
FROM
QUERIE.PARCELA_TOTAL_CORRECAO PTC
WHERE
PTC.CTO_IN_CODIGO = 14393
) PTC
ON PTC.CTO_IN_CODIGO = PT.CTO_IN_CODIGO
AND PTC.PAR_IN_CODIGO = PT.PAR_IN_CODIGO
AND PTC.HPAR_IN_CODIGO = PT.HPAR_IN_CODIGO
AND PTC.PARCOR_IN_CODIGO = PTC.PARCOR_IN_CODIGO_MAX
WHERE
PT.HPAR_IN_CODIGO = PT.HPAR_IN_CODIGO_MAX
what is confusing to me is that the with clause returns just one row with the cto_in_codigo number, much like if I hard code then inside each query like the second code. What is could be causing this super delay?

Deleting rows from a SQL table based on specific criteria

I have a table that contains the following fields: issues to go (itg), customer number (ctm_nbr) and pub code (pub_cde). The data looks like this
12 010000024412 CTR
6 010000024412 RTF
18 010000002325 CTR
9 010000002325 RTF
3 010000014789 CTR
1 010000014789 RTF
I need to be able to delete all of the records where the RTF pub code and matching customer number is half of the issues to go (itg) in the CTR pub code for that matching customer. That way once I have all the records removed I would only have records like this remaining:
3 010000014789 CTR
1 010000014789 RTF
You might use something like: Delete all records for customer number x where the customer number has issues to go in CTR field that are twice the issues to go in the RTF field.
Delete
from --table--
where ctm_nbr in (select t2.ctm_nbr
from --table-- t2 join --table-- t3
ON (t2.ctm_nbr = t3.ctm_nbr)
where t2.pub_cde="CTR"
and t3.pub_cde="RTF"
and t2.itg = 2*t3.itg
)
The tricky bit is getting both related records at one time:
delete
a1
from
a a1
where (
a1.pub_cde = 'RTF' and
exists (
select 'x'
from a a2
where a2.ctm_nbr = a1.ctm_nbr and
a2.pub_cde = 'CTR' and
a2.itg = 2 * a1.itg
)
) or (
a1.pub_cde = 'CTR' and
exists (
select 'x'
from a a2
where a2.ctm_nbr = a1.ctm_nbr and
a2.pub_cde = 'RTF' and
a2.itg * 2 = a1.itg
)
);
Example SQL Fiddle
You can use conditional aggregation:
delete from tbl
where ctm_nbr in(
select ctm_nbr
from tbl
group by ctm_nbr
having max(case when pub_cde = 'CTR' then cast(itg as decimal) end) /
max(case when pub_cde = 'RTF' then cast(itg as decimal) end) = 2)
Fiddle: http://sqlfiddle.com/#!6/a7efe/1/0
The reason I casted itg as decimal is to avoid the rounding issue that would otherwise occur due to your column being an interger data type (thanks to Laurence for pointing that out).
DELETE t1
FROM a t1
INNER JOIN a t2
ON t1.ctm_nbr = t2.ctm_nbr
WHERE
((t1.pub_cde = 'CTR') AND
(t2.pub_cde = 'RTF') AND
(2*t2.itg = t1.itg))
OR
((t2.pub_cde = 'CTR') AND
(t1.pub_cde = 'RTF') AND
(2*t1.itg = t2.itg))

Where to add index?

I'm trying to figure out where I could add an index or modify an existing one to make the query go faster.
Main problem is that I cannot change the query itself, it's generated by Business Objects.
The strange thing is that if I change the WHERE clause to use another table, then the query is really fast!
The query is the following:
SELECT Year(listingperformanceindicator.date),
Month(listingperformanceindicator.date),
categoryflattened.parentname,
categoryflattened.groupname,
categoryflattened.categoryname,
Count(listingperformanceindicator.listingid),
( Count(listingperformanceindicator.listingid) ) / 30,
Sum(listingperformanceindicator.listingviews),
CASE
WHEN ( ( Count(listingperformanceindicator.listingid) ) / 30 ) = 0 THEN
0
ELSE ( Sum(listingperformanceindicator.listingviews) ) /
( ( Count(listingperformanceindicator.listingid) ) / 30 )
END
FROM listingperformanceindicator
RIGHT OUTER JOIN categorytolisting
ON ( categorytolisting.siteid = listingperformanceindicator.siteid
AND categorytolisting.listingid = listingperformanceindicator.listingid )
RIGHT OUTER JOIN categoryflattened
ON ( categoryflattened.siteid = categorytolisting.siteid
AND ( categoryflattened.parentid = categorytolisting.categoryid
OR categoryflattened.categoryid = categorytolisting.categoryid
OR categoryflattened.groupid = categorytolisting.categoryid ) )
RIGHT OUTER JOIN site ON (site.id=categoryflattened.siteId)
WHERE --listingperformanceindicator.siteid = 'DED29E78-17B0-423B-A1D1-67E2F3CA864D' --THIS IS REALLY FAST :/
site.id = 'DED29E78-17B0-423B-A1D1-67E2F3CA864D' --THIS IS REALLY SLOW! :(
AND categoryflattened.languagecode ='SE'
GROUP BY Year(listingperformanceindicator.date),
Month(listingperformanceindicator.date),
categoryflattened.parentname,
categoryflattened.groupname,
categoryflattened.categoryname
I've tried looking at the execution plan but it makes no sense to me :(
Here they are:
fast: http://imageshack.us/a/img211/5755/fastquery.png
slow: http://imageshack.us/a/img823/7227/slowquery.png
Any suggestion appreciated!
Thanks!