Levidoom
Levidoom

Reputation: 84

Optimization of SQL query with multiple unions

Does anybody know how to make this query a bit shorter? The problem, and reason why I am asking this is is that it takes a long time to process the query because the query returns over 16K records.

SELECT p.broj, p.mje_osig, p.id_cjen, p.poc_dat, p.ist_dat, ' ' AS nac_prem,
         1 AS gr_red, s.rbr, s.serial, s.vs, s.stat_id, s.naziv, 
         s.osnov*s.kol_dok AS osnovica, s.stopa, s.premija*s.kol_dok AS premija 
     FROM osiguranje.police_osn p, osiguranje.st_pol s 
     WHERE p.broj=s.broj AND 
        XUvjet+ AND s.vs='SO' AND s.premija<>0 
UNION ALL 
SELECT p.broj, p.mje_osig, p.id_cjen, p.poc_dat, p.ist_dat, ' ' AS nac_prem, 
        1 AS gr_red, s.rbr, s.serial, s.vs, s.stat_id, s.naziv, 
        s.osnov AS osnovica, s.stopa, s.premija 
     FROM osiguranje.police_osn p, osiguranje.st_pol s 
     WHERE p.broj=s.broj AND 
        XUvjet AND s.vs='DO' AND s.premija<>0 
UNION ALL 
SELECT p.broj, p.mje_osig, p.id_cjen, p.poc_dat, p.ist_dat, ' ' AS nac_prem, 
        1 AS gr_red, s.rbr, s.serial, s.vs, s.stat_id, s.naziv, 
        s.osnov AS osnovica, s.stopa, -s.premija AS premija 
    FROM osiguranje.police_osn p, osiguranje.st_pol s 
    WHERE p.broj=s.broj AND 
        XUvjet AND s.vs='PO' AND s.premija<>0 
UNION ALL 
SELECT p.broj, p.mje_osig, p.id_cjen, p.poc_dat, p.ist_dat, ' ' AS nac_prem, 
         1 AS gr_red, s.rbr, s.serial, s.vs, s.stat_id, s.naziv, 
         s.osnov*s.kol_dok AS osnovica, s.stopa, s.premija*s.kol_dok AS premija 
    FROM osiguranje.police_osn p, osiguranje.st_pril s 
    WHERE p.broj=s.broj AND 
        XUvjet AND s.vs='SO' AND s.premija<>0 
UNION ALL 
SELECT p.broj, p.mje_osig, p.id_cjen, p.poc_dat, p.ist_dat, ' ' AS nac_prem, 
        1 AS gr_red, s.rbr, s.serial, s.vs, s.stat_id, s.naziv, 
        s.osnov AS osnovica, s.stopa, s.premija 
    FROM osiguranje.police_osn p, osiguranje.st_pril s 
    WHERE p.broj=s.broj AND 
        XUvjet AND s.vs='DO' AND s.premija<>0 
UNION ALL 
SELECT p.broj, p.mje_osig, p.id_cjen, p.poc_dat, p.ist_dat, ' ' AS nac_prem, 
        1 AS gr_red, s.rbr, s.serial, s.vs, s.stat_id, s.naziv, 
        s.osnov AS osnovica, s.stopa, -s.premija AS premija 
    FROM osiguranje.police_osn p, osiguranje.st_pril s 
    WHERE p.broj=s.broj AND 
        XUvjet AND s.vs='PO' AND s.premija<>0 
UNION ALL 
SELECT p.broj, p.mje_osig, p.id_cjen, p.poc_dat, p.ist_dat, q.nac_prem, 
        0 AS gr_red, s.rbr, s.serial, s.vs, s.stat_id, s.naziv, 
        s.osnov AS osnovica, s.stopa, s.premija 
    FROM osiguranje.police_osn p, osiguranje.skup_os q, osiguranje.st_pol s 
    WHERE p.proizvod=q.sifra AND p.broj=s.broj AND 
        XUvjet AND s.vs='DK' AND s.stopa<>0 
UNION ALL 
SELECT p.broj, p.mje_osig, p.id_cjen, p.poc_dat, p.ist_dat, q.nac_prem, 
        0 AS gr_red, s.rbr, s.serial, s.vs, s.stat_id, s.naziv, 
        s.osnov AS osnovica, -s.stopa AS stopa, s.premija 
    FROM osiguranje.police_osn p, osiguranje.skup_os q, osiguranje.st_pol s 
    WHERE p.proizvod=q.sifra AND p.broj=s.broj AND 
        XUvjet  AND s.vs='PK' AND s.stopa<>0 
ORDER BY p.broj, gr_red, s.rbr, s.serial 

XUvjet is a variable that'll be inserted in a C# code.

Upvotes: 0

Views: 74

Answers (2)

jwolf
jwolf

Reputation: 938

You can combine all those Where clauses, like this:

SELECT p.broj, p.mje_osig, p.id_cjen, p.poc_dat, p.ist_dat, ' ' AS nac_prem,
         1 AS gr_red, s.rbr, s.serial, s.vs, s.stat_id, s.naziv, 
         s.osnov*s.kol_dok AS osnovica, s.stopa, s.premija*s.kol_dok AS premija 
     FROM osiguranje.police_osn p, osiguranje.st_pol s 
     WHERE (p.broj=s.broj AND XUvjet+ AND s.vs='SO' AND s.premija<>0)
         or(p.broj=s.broj AND XUvjet AND s.vs='DO' AND s.premija<>0)
         or (p.broj=s.broj AND XUvjet AND s.vs='PO' AND s.premija<>0)
UNION ALL 
SELECT p.broj, p.mje_osig, p.id_cjen, p.poc_dat, p.ist_dat, ' ' AS nac_prem, 
         1 AS gr_red, s.rbr, s.serial, s.vs, s.stat_id, s.naziv, 
         s.osnov*s.kol_dok AS osnovica, s.stopa, s.premija*s.kol_dok AS premija 
    FROM osiguranje.police_osn p, osiguranje.st_pril s 
    WHERE (p.broj=s.broj AND XUvjet AND s.vs='SO' AND s.premija<>0)
        or (p.broj=s.broj AND XUvjet AND s.vs='DO' AND s.premija<>0)
        or (p.broj=s.broj AND XUvjet AND s.vs='PO' AND s.premija<>0)
UNION ALL    
SELECT p.broj, p.mje_osig, p.id_cjen, p.poc_dat, p.ist_dat, q.nac_prem, 
        0 AS gr_red, s.rbr, s.serial, s.vs, s.stat_id, s.naziv, 
        s.osnov AS osnovica, s.stopa, s.premija 
    FROM osiguranje.police_osn p, osiguranje.skup_os q, osiguranje.st_pol s 
    WHERE (p.proizvod=q.sifra AND p.broj=s.broj AND XUvjet AND s.vs='DK' AND s.stopa<>0)
        or (p.proizvod=q.sifra AND p.broj=s.broj AND XUvjet  AND s.vs='PK' AND s.stopa<>0) 

I hope this helps.

Upvotes: 1

Vahid
Vahid

Reputation: 1949

For the s.vs in WHERE clause you can easily use the IN operator:

WHERE s.vs IN ['PK', 'DK', 'PO', ...]

For the gr_red in SELECT clause you can use the CASE-WHEN operator:

SELECT  ' ' AS nac_prem, gr_red =
      CASE
         WHEN s.vs='PK' THEN 0
         WHEN  XUvjet AND s.vs='PO' THEN 1
         ELSE 1
      END,

Obviously you can add more logic to the WHEN clause here to make it fit the logic of your query.

Upvotes: 1

Related Questions