I have the following stored procedure (in MS SQL):
SET NOCOUNT ON
DECLARE #Cuantos INT
IF EXISTS
(
SELECT TOP 1 * FROM IntProgramas WHERE cod_programa IN
( SELECT cod_programa FROM IntGrupo_programa WHERE cod_grupo IN
( SELECT cod_grupo FROM IntUsuarios WHERE cod_usuario = #cod_usuario
)
)
)
BEGIN
SET nocount ON
SELECT P.cod_programa
,nb_programa
,descripcion
,secuencia
,P.Accion
,P.Controlador
INTO #mitabla1
FROM IntProgramas P
WHERE P.cod_programa
IN (
SELECT cod_programa FROM Intgrupo_programa WHERE cod_grupo IN
(
SELECT cod_grupo FROM Intusuarios WHERE cod_usuario=#cod_usuario
)
)
SET nocount ON
SELECT GP.cod_programa
,P.nb_programa
,P.descripcion
INTO #mitabla2
FROM IntGrupo_Programa GP
JOIN Intprogramas P on GP.cod_programa = P.cod_programa
WHERE GP.cod_grupo IN (SELECT cod_grupo FROM Intusuarios WHERE cod_usuario=#cod_usuario
SELECT #Cuantos = COUNT(*)
FROM( SELECT nb_programa, descripcion FROM IntProgramas
WHERE cod_programa in (select cod_programa from #mitabla1
union select cod_programa from #mitabla2))x
/*si existe en ambas macheo*/
SELECT nb_programa, descripcion, P.cod_programa
INTO #mitabla3
FROM IntProgramas P
WHERE cod_programa in (SELECT cod_programa FROM #mitabla1
union SELECT cod_programa FROM #mitabla2)
select
t.nb_programa
, t.descripcion
, t.cod_programa
, p.secuencia
, ISNULL(et.cod_menu,0) as cod_menu
, ISNULL(et.desc_menu,0) as desc_menu
, ISNULL(et_sprog.cod_sub_menu_programa,0) AS cod_sub_menu_programa
, ISNULL(et_sprov.desc_sub_menu,0) AS desc_sub_menu_N2
, p.Accion
, p.Controlador
from #mitabla3 t
JOIN IntProgramas p
ON t.cod_programa = p.cod_programa
LEFT JOIN IntEstructura_sub_menu_programa et_sprog
ON t.cod_programa = et_sprog.cod_programa
LEFT JOIN IntEstructura_menu_Usuarios et
ON et_sprog.cod_menu = et.cod_menu
LEFT JOIN IntEstructura_sub_menu_Usuarios et_sprov
ON et_sprog.cod_sub_menu_programa = et_sprov.cod_sub_menu
WHERE et_sprog.cod_programa IS NOT NULL
order by et.cod_menu, et_sprog.cod_sub_menu_programa, p.secuencia
--gp.cod_grupo,
drop table #mitabla1
drop table #mitabla2
drop table #mitabla3
END
i am trying to understand it but when I get to the line
union select cod_programa from #mitabla2))x
I don't understand what the x does any help would be apreciated.
I have been trying to run the SP in parts to better understand the flow but that line has really complicated things for me.
X is an alias for this sub-query or derived table:
( SELECT nb_programa, descripcion FROM IntProgramas
WHERE cod_programa in (select cod_programa from #mitabla1
union select cod_programa from #mitabla2))
It's an alias for the subquery:
select #Cuantos = COUNT(*)
from (
select nb_programa, descripcion
from IntProgramas
where cod_programa in (
select cod_programa
from #mitabla1
union
select cod_programa
from #mitabla2
)
) x
When you do SELECT FROM (SELECT... you have to name the subquery / derived table.
It works as if you were doing:
select #Cuantos = COUNT(*)
from x
Unlike an alias in a table name that is used mostly to make it easier to read or to not have to repeat the table name, in this case an alias is mandatory.
X is the alias for the results of the sub-query. There should really be a space before it though
Related
I have a query which is taking a long time. Is there anyway to write it better and in optimized way:
select 1, my_text from (
select distinct a.my_text||'_'||b.my_text my_text from (
select r_id, my_text
from tmp_v
where r_id in (
select o_id
from tmp_recid
) and v_id in (
select v_id
from o_v
where v_id in (
select o_id from tmp_record_vaid
union
select o_id from tmp_vue_vaid
) and va_nm = 'My V'
)
) a,
(
select r_id, my_text
from tmp_v
where r_id in (
select o_id
from tmp_recid
) and v_id in (
select v_id
from o_v
where v_id in (
select o_id from tmp_record_vaid
union
select o_id from tmp_vue_vaid
) and va_nm = 'My V 2'
)
) b
where a.r_id = b.r_id
except
select e_nm
from myp_ent_id
where p_m_id = 1 and entity_id in (
select entity_id
from o_e_t
where p_m_id = 1 and tag = 'Ample' and tag_category = 'My Type'
)
) a;
please, try with below query except "except query":
select 1, distinct(CONCAT(TV1.my_text, '_'))
from tmp_v TV1
left outer join tmp_recid TR1 on TR1.o_id = TV1.r_id
left outer join o_v OV1 on OV1.v_id = TV1.v_id and OV1.va_nm in ('My V', 'My V 2')
left outer join tmp_record_vaid TRV1 on OV1.v_id = TRV1.o_id
left outer join tmp_vue_vaid TVV1 on OV1.v_id = TVV1.o_id
where TR1.o_id is not null and (TRV1.o_id is not null OR TVV1.o_id is not null)
group by TV1.r_id
First level optimization: I combined two sub queries a and b(tmp_v) into one using CASE as the conditions are common for both.
select 1,my_text(
select distinct string_agg(amytext,'')||'_'||string_agg(bmytext,'') as mytext(
select r_id,case va_nm='My V' then my_text else null end as amy_text,case va_nm='My V 2' then my_text else null end as bmy_text
from tmp_v
where r_id in
(select o_id from tmp_recid)
and v_id in (select v_id from o_v where v_id in (select o_id from tmp_record_vaid union select o_id from tmp_vue_vaid))
)
except
select e_nm
from myp_ent_id
where p_m_id = 1 and entity_id in (
select entity_id
from o_e_t
where p_m_id = 1 and tag = 'Ample' and tag_category = 'My Type'
)
)a;
Further you can replace IN with EXISTS.
I have this query but it's not working. Can you tell me the solution?
update temp_msisdn_saldo
set saldo=(
select sum(saldo) from (
select a.msisdn as mdn, a.saldo from temp_msisdn_saldo a
union all
select b.mdn as mdn, b.saldo from temp_msisdn_saldo_yesterday b
) z
)
where msisdn=z.mdn
You can rewrite it as :
update temp_msisdn_saldo
set saldo = ( select sum(saldo)
from (select a.msisdn as mdn, a.saldo
from temp_msisdn_saldo a
union all
select b.mdn as mdn, b.saldo
from temp_msisdn_saldo_yesterday b
) z
where z.mdn = temp_msisdn_saldo.msisdn
);
Same you can use CTE :
with cte as (
<your query here>
)
update temp_msisdn_saldo
set saldo = (select sum(c.saldo) from cte c where c.mdn = temp_msisdn_saldo.msisdn);
I have a query which looks like this:
SELECT DISTINCT * FROM (
SELECT FundId AS Id,
PeriodYearMonth
FROM [Fund.Period] F
INNER JOIN (
SELECT * FROM (
SELECT FundId as Id,
MIN(PeriodYearMonth) AS MinPeriodYearMonth
FROM (
SELECT FundId,
PeriodYearMonth,
PublishedOn
FROM [Fund.Period] FP
UNION ALL --Changed to UNION ALL as it is more efficient and we wont ever need a UNION as the result set would never match
SELECT FundId,
MAX(PeriodYearMonth) + 1,
NULL
FROM [Fund.Period]
GROUP BY FundId
) FP WHERE PublishedOn IS NULL GROUP BY FundId
) MFP
) FP ON F.FundId = FP.Id AND (F.PeriodYearMonth = FP.MinPeriodYearMonth OR (f.PeriodYearMonth +1) = FP.MinPeriodYearMonth)
) FP
If possible, I would like to remove the UNION ALL. Does anyone know how this can be optimized?
removed union all
SELECT DISTINCT * FROM (
SELECT FundId AS Id,
PeriodYearMonth
FROM [Fund.Period] F
INNER JOIN (
SELECT * FROM (
SELECT FundId as Id,
MIN(PeriodYearMonth) AS MinPeriodYearMonth,MAX(PeriodYearMonth) + 1 as PeriodYearMonth
FROM (
SELECT FundId,
PeriodYearMonth,
PublishedOn
FROM [Fund.Period] FP
) FP WHERE PublishedOn IS NULL
GROUP BY FundId
) MFP
) FP ON F.FundId = FP.Id AND (F.PeriodYearMonth = FP.MinPeriodYearMonth OR (f.PeriodYearMonth +1) = FP.MinPeriodYearMonth)
) FP
I'm trying to do following but getting an max recursive error. Can someone please help?
Sample code to demonstrate what I'm trying to achieve:
DECLARE #SecurityMaster AS TABLE
(
ID INT,
SecurityAlias INT,
LegNumber INT
)
INSERT INTO #SecurityMaster
SELECT 12829, 3030106, NULL
UNION ALL
SELECT 12829, 3030107, 1
SELECT * FROM #SecurityMaster;
WITH CTE1 (ID, SecurityAlias, LegNumber)
AS
(
SELECT S.ID, S.SecurityAlias, S.LegNumber
FROM #SecurityMaster S
WHERE S.LegNumber IS NOT NULL
UNION ALL
select s.ID, s.SecurityAlias, s.LegNumber
from #SecurityMaster S inner join CTE1 c on s.ID = c.ID
where s.LegNumber is NULL
)
SELECT *
FROM CTE1;
Result I'm expecting:
ID SecurityAlias LegNumber
-----------------------------------------
12829 3030107 1
12829 3030106 NULL
Your questionis difficult to understand, but will this work for you?
select s.ID, s.SecurityAlias, s.LegNumber
from #SecurityMaster S
where s.LegNumber is NULL
And s.id in (SELECT f.ID
FROM #SecurityMaster f
WHERE f.LegNumber IS NOT NULL)
Create table #tmptble(RuleId, SubjectId, RID, Date)
Insert into #tmptble(RuleId,SubjectId, RID, Date)
Select RuleTable.RuleId, RuleTable.SubjectId, KeyTable.RID, KeyTable.ParentId
FROM RuleTable INNER JOIN KeyTable
ON KeyTable.RID = RuleTable.RID
This query is very slow. I have an clustered index on RID on KeyTable, clustered index on RuleId on RuleTable, Unique non clustered index on RuleId+SubjectId on the RuleTable. (RuleTable is used in various other places)
In the above query if I introduce a where clause like
Insert into #tmptble(RuleId,SubjectId, RID, Date)
Select RuleTable.RuleId, RuleTable.SubjectId, KeyTable.RID, KeyTable.ParentId
FROM RuleTable INNER JOIN KeyTable
ON KeyTable.RID = RuleTable.RID
WHERE KeyTable.RID = #RID -- #RID is passed into the storedproc
the running time reduces by > 50%. But the problem is that I use the original table result without the WHERE clause in the following way
WITH ResourceTree AS
(
SELECT
#tmptble.RuleId AS [RuleId],
#tmptble.SubjectId AS [SubjectRecId],
#tmptble.RId AS [RId],
#tmptble.ParentID AS [ParentID]
FROM #tmptble WHERE #tmptble.SubjectId = #SubjectId
AND #tmptble.RId = #RId
UNION ALL
-- Recursive step
-- Note that the recursive step uses the results from original #tmptable
SELECT
#tmptble.RuleId AS [RuleId],
#tmptble.SubjectId AS [SubjectId],
#tmptble.RId AS [RId],
#tmptble.ParentID AS [ParentID]
FROM #tmptble INNER JOIN ResourceTree RT
ON RT.ParentID = #tmptble.RId
)
SELECT *
FROM ResourceTree
Is there a way to optimize this query? Any kind of suggestions regarding indexes or way recursion is done would be helpful
Possible this be helpful for you -
;WITH temp AS
(
SELECT
r.RuleId
, r.SubjectId
, r.RID
, k.ParentId
FROM (
SELECT r.*
FROM dbo.RuleTable r
WHERE r.RID = #RID
) r
JOIN dbo.KeyTable k ON k.RID = r.RID
)
, ResourceTree AS
(
SELECT
t.RuleId
, [SubjectRecId] = t.SubjectId
, t.RId
, t.ParentID
FROM temp t
WHERE t.SubjectId = #SubjectId
UNION ALL
SELECT
t.RuleId
, t.SubjectId
, t.RId
, t.ParentID
FROM temp t
WHERE EXISTS (
SELECT 1
FROM ResourceTree r
WHERE r.ParentID = t.RId
)
)
SELECT *
FROM ResourceTree