În primul rând, în loc de "acc_new_codfiscal like '%1%' or acc_new_codfiscal like '%2%' or ..." putem să scriem "acc_new_codfiscal like '%[0-9]%'".
Apoi, observăm că se repetă (de 4 ori) următoarea porţiune:
select min(acc_id) cstid, min(acc_new_codfiscal) cstafm from vw_crmimportclienti
where acc_new_codfiscal in (
select acc_new_codfiscal from vw_crmimportclienti
where acc_new_codfiscal like '%[0-9]%'
group by acc_new_codfiscal
having count(acc_new_codfiscal) > 1)
group by acc_new_codfiscal
Pentru a fi mai uşor de citit, am putea folosi un CTE în SQL 2005 sau un view în SQL 2000. Totuşi, în acest caz, cred că am obţine o performanţă ceva mai bună cu o tabelă temporară. Pe de altă parte, dacă avem "group by
acc_new_codfiscal" atunci "min(acc_new_codfiscal)" înseamnă pur şi
simplu "acc_new_codfiscal". Deci:
CREATE TABLE #T (
cstafm varchar(10) PRIMARY KEY,
cstid int
)
INSERT INTO #T (cstafm, cstid)
select acc_new_codfiscal, min(acc_id) from vw_crmimportclienti
where acc_new_codfiscal in (
select acc_new_codfiscal from vw_crmimportclienti
where acc_new_codfiscal like '%[0-9]%'
group by acc_new_codfiscal
having count(acc_new_codfiscal) > 1)
group by acc_new_codfiscal
select x.*,y.code CodAgent from (
select cst.*, x.cstid IDSUP from vw_crmimportclienti cst
left join #T x on cst.acc_new_codfiscal = x.cstafm and cst.acc_id > x.cstid
where x.cstid is not null and cst.comid = 3
union all
select cst.*, null IDSUP from vw_crmimportclienti cst
left join #T x on cst.acc_new_codfiscal = x.cstafm and cst.acc_id = x.cstid
where x.cstid is not null and cst.comid = 3
union all
select *, null IDSUP from vw_crmimportclienti cst
where acc_id not in (
select acc_id from vw_crmimportclienti cst
left join #T x on cst.acc_new_codfiscal = x.cstafm and cst.acc_id > x.cstid
where x.cstid is not null and cst.comid = 3
union all
select acc_id from vw_crmimportclienti cst
left join #T x on cst.acc_new_codfiscal = x.cstafm and cst.acc_id = x.cstid
where x.cstid is not null and cst.comid = 3
)
) x inner join (
select sal.Code code,ftr.cusid cusid
from (
SELECT ftr.cusid, min(ftr.id) ftrid
FROM dbo.FINTRADE ftr
INNER JOIN dbo.ITEMTRANS itt ON ftr.ID=itt.FTRID
WHERE ftr.SOURCE=5 AND itt.BILLEDOUTPUT=1
GROUP BY cusid
) z join fintrade ftr on ftr.id=z.ftrid
INNER JOIN Salesman sal on ftr.COLIDSALESMAN = sal.id
) y on x.acc_id=y.cusid
DROP TABLE #T
Te-aş ruga să încerci query-ul de mai sus, să îmi spui cum stăm cu performanţa până aici.
În continuare, am putea să mai simplificăm UNION-urile respective, astfel:
1. Dacă avem LEFT JOIN iar apoi condiţie cu "WHERE x.cstid IS NOT NULL" înseamnă că de fapt avem INNER JOIN.
2. Putem primele două componente ale UNION ALL-ului diferă doar prin condiţia "cst.acc_id > x.cstid", respectiv "cst.acc_id = x.cstid" şi prin coloana IDSUP (care în al doilea caz e NULL), deci putem să le rescriem astfel:
select cst.*, NULLIF(x.cstid,cst.acc_id) IDSUP from vw_crmimportclienti cst
inner join #T x on cst.acc_new_codfiscal = x.cstafm and cst.acc_id >= x.cstid
where cst.comid = 3
3. În UNION ALL-ul din subquery-ul care urmează după "where acc_id not in (", diferenţa este similară cu cea de mai sus, numai că nu mai avem deloc coloana IDSUP, deci putem să o simplificăm într-un mod similar, obţinând în final:
CREATE TABLE #T (
cstafm varchar(10) PRIMARY KEY,
cstid int
)
INSERT INTO #T (cstafm, cstid)
select acc_new_codfiscal, min(acc_id) from vw_crmimportclienti
where acc_new_codfiscal in (
select acc_new_codfiscal from vw_crmimportclienti
where acc_new_codfiscal like '%[0-9]%'
group by acc_new_codfiscal
having count(acc_new_codfiscal) > 1)
group by acc_new_codfiscal
select x.*,y.code CodAgent from (
select cst.*, NULLIF(x.cstid,cst.acc_id) IDSUP from vw_crmimportclienti cst
inner join #T x on cst.acc_new_codfiscal = x.cstafm and cst.acc_id >= x.cstid
where cst.comid = 3
union all
select *, null IDSUP from vw_crmimportclienti cst
where acc_id not in (
select acc_id from vw_crmimportclienti cst
inner join #T x on cst.acc_new_codfiscal = x.cstafm and cst.acc_id >= x.cstid
where cst.comid = 3
)
) x inner join (
select sal.Code code,ftr.cusid cusid
from (
SELECT ftr.cusid, min(ftr.id) ftrid
FROM dbo.FINTRADE ftr
INNER JOIN dbo.ITEMTRANS itt ON ftr.ID=itt.FTRID
WHERE ftr.SOURCE=5 AND itt.BILLEDOUTPUT=1
GROUP BY cusid
) z join fintrade ftr on ftr.id=z.ftrid
INNER JOIN Salesman sal on ftr.COLIDSALESMAN = sal.id
) y on x.acc_id=y.cusid
DROP TABLE #T
Te rog încearcă şi query-ul de mai sus şi spune-mi cum stăm cu performanţa.
Următorul pas ar fi unificarea celor două componente a UNION-ului care a mai rămas, dar aici nu mai sunt foarte sigur că obţinem aceleaşi rezultate (în mod normal, ar trebui să fie la fel, dar fac nişte presupuneri în privinţa datelor din vw_crmimportclienti, pe care nu pot să le exprim foarte clar). Aşa că înainte de a face acest pas, aş avea nevoie să ştiu dacă putem considera că acc_id e cheie primară în vw_crmimportclienti (îmi dau seama că e un view şi că nu are definite niciun fel de chei, dar vreau să ştiu dacă luând în considerare cheile unice pe tabelele de bază şi modul în care e scris view-ul vw_crmimportclienti, rezultă dpdv logic că acc_id e totdeauna ne-nul şi că nu pot apare două rânduri în acest view cu aceeaşi valoare pentru acc_id ?).
Răzvan