Results 1 to 6 of 6

Thread: Union all

  1. #1

    Union all

    Hallo,

    Ik heb een query gemaakt waarbij ik per maand een bepaalde SUM doe.
    Nu heb ik om alle 12 maanden naast elkaar te krijgen een query gemaakt met daarin 12 keer een UNION ALL

    Code:
    SELECT
      ALUMUTATIE.cltnr AS klantnummer,
      ALUCLIENT.faccltnr,
      ALUMUTATIE.wksnr AS uvwcode,
      Concat(ALUMUTATIE.wksnr, ' - ', ALUWERKSOORT.omsch) AS UVWOmschrijvingFull,
      ALUMUTATIE.jaar AS opdracht,
      Year(ALUMUTATIE.mudat) AS MuatieJaar,
      ALUDECLARATIE.decnr,
      ALUDECLARATIE.datum_aanmaak AS decdt,
      ALUDECLARATIE.facjr,
      ALUDECLARATIE.facdt,
      ALUDECLARATIE.facpr,
      ALUDECLARATIE.facnr,
      DatePart(mm, ALUDECLARATIE.facdt) - 1 AS Periode,
      Sum(ALUMUTATIE.mutbd) AS Januari,
      0 AS februari,
      0 AS maart,
      0 AS april,
      0 AS mei,
      0 AS juni,
      0 AS juli,
      0 AS augustus,
      0 AS september,
      0 AS oktober,
      0 AS november,
      0 AS december,
      ALUWERKSOORTGROEP.wgrnr,
      ALUWERKSOORTGROEP.omsch
    FROM
      ALUMUTATIE
      LEFT JOIN ALUDECLARATIE ON ALUMUTATIE.decnr = ALUDECLARATIE.decnr
      LEFT JOIN ALUWERKSOORT ON ALUMUTATIE.wksnr = ALUWERKSOORT.wksnr
      INNER JOIN RELATIE Medewerker ON Medewerker.dossiernum = ALUMUTATIE.mdwnr
      INNER JOIN RELATIE Klant ON Klant.dossiernum = ALUMUTATIE.cltnr
      LEFT JOIN ALUWERKSOORTGROEP ON ALUWERKSOORT.admnr = ALUWERKSOORTGROEP.admnr AND ALUWERKSOORT.wgrnr =
        ALUWERKSOORTGROEP.wgrnr
      INNER JOIN ALUCLIENT ON ALUCLIENT.relnr = Klant.relnr
    WHERE
      ALUMUTATIE.corcd = 0 AND
      ALUMUTATIE.type = 1 AND
      ((DatePart(mm, DateAdd(m, -1, ALUDECLARATIE.facdt)) = 1) OR
        (DatePart(mm, DateAdd(m, -1, ALUDECLARATIE.datum_aanmaak)) = 1)) AND
      ((ALUDECLARATIE.facnr IS NULL AND
          ALUCLIENT.faccltnr IS NOT NULL) OR
        (ALUDECLARATIE.facnr IS NOT NULL) OR
        (ALUDECLARATIE.decnr IS NOT NULL))
    GROUP BY
      ALUMUTATIE.cltnr,
      ALUCLIENT.faccltnr,
      ALUMUTATIE.wksnr,
      Concat(ALUMUTATIE.wksnr, ' - ', ALUWERKSOORT.omsch),
      ALUMUTATIE.jaar,
      Year(ALUMUTATIE.mudat),
      ALUDECLARATIE.decnr,
      ALUDECLARATIE.datum_aanmaak,
      ALUDECLARATIE.facjr,
      ALUDECLARATIE.facdt,
      ALUDECLARATIE.facpr,
      ALUDECLARATIE.facnr,
      ALUWERKSOORTGROEP.wgrnr,
      ALUWERKSOORTGROEP.omsch
    
    UNION ALL
    
    SELECT
      ALUMUTATIE.cltnr AS klantnummer,
      ALUCLIENT.faccltnr,
      ALUMUTATIE.wksnr AS uvwcode,
      Concat(ALUMUTATIE.wksnr, ' - ', ALUWERKSOORT.omsch) AS UVWOmschrijvingFull,
      ALUMUTATIE.jaar AS opdracht,
      Year(ALUMUTATIE.mudat) AS MuatieJaar,
      ALUDECLARATIE.decnr,
      ALUDECLARATIE.datum_aanmaak AS decdt,
      ALUDECLARATIE.facjr,
      ALUDECLARATIE.facdt,
      ALUDECLARATIE.facpr,
      ALUDECLARATIE.facnr,
      DatePart(mm, ALUDECLARATIE.facdt) - 1 AS Periode,
      0 AS Januari,
      Sum(ALUMUTATIE.mutbd) AS februari,
      0 AS maart,
      0 AS april,
      0 AS mei,
      0 AS juni,
      0 AS juli,
      0 AS augustus,
      0 AS september,
      0 AS oktober,
      0 AS november,
      0 AS december,
      ALUWERKSOORTGROEP.wgrnr,
      ALUWERKSOORTGROEP.omsch
    FROM
      ALUMUTATIE
      LEFT JOIN ALUDECLARATIE ON ALUMUTATIE.decnr = ALUDECLARATIE.decnr
      LEFT JOIN ALUWERKSOORT ON ALUMUTATIE.wksnr = ALUWERKSOORT.wksnr
      INNER JOIN RELATIE Medewerker ON Medewerker.dossiernum = ALUMUTATIE.mdwnr
      INNER JOIN RELATIE Klant ON Klant.dossiernum = ALUMUTATIE.cltnr
      LEFT JOIN ALUWERKSOORTGROEP ON ALUWERKSOORT.admnr = ALUWERKSOORTGROEP.admnr AND ALUWERKSOORT.wgrnr =
        ALUWERKSOORTGROEP.wgrnr
      INNER JOIN ALUCLIENT ON ALUCLIENT.relnr = Klant.relnr
    WHERE
      ALUMUTATIE.corcd = 0 AND
      ALUMUTATIE.type = 1 AND
      ((DatePart(mm, DateAdd(m, -1, ALUDECLARATIE.facdt)) = 2) OR
        (DatePart(mm, DateAdd(m, -1, ALUDECLARATIE.datum_aanmaak)) = 2)) AND
      ((ALUDECLARATIE.facnr IS NULL AND
          ALUCLIENT.faccltnr IS NOT NULL) OR
        (ALUDECLARATIE.facnr IS NOT NULL) OR
        (ALUDECLARATIE.decnr IS NOT NULL))
    GROUP BY
      ALUMUTATIE.cltnr,
      ALUCLIENT.faccltnr,
      ALUMUTATIE.wksnr,
      Concat(ALUMUTATIE.wksnr, ' - ', ALUWERKSOORT.omsch),
      ALUMUTATIE.jaar,
      Year(ALUMUTATIE.mudat),
      ALUDECLARATIE.decnr,
      ALUDECLARATIE.datum_aanmaak,
      ALUDECLARATIE.facjr,
      ALUDECLARATIE.facdt,
      ALUDECLARATIE.facpr,
      ALUDECLARATIE.facnr,
      ALUWERKSOORTGROEP.wgrnr,
      ALUWERKSOORTGROEP.omsch
    Het voordeel hiervan is dat het werkt. Het nadeel is dat de query heel erg groot wordt. Maar mijn gevoel zegt dat dit makkelijk kan echter zie ik niet hoe. Iemand een idee?

    Nu heb van deze query met 12 periodes een VIEW gemaakt. Ik heb een 8 tal vergelijkbare query's met andere WHERE opties waarvan ik ook een VIEW heb gemaakt. Het resultaat wordt weer opgehaald in een andere VIEW. Resultaat is dat het allemaal erg traag is geworden.

    Nu heb ik gelezen dat het nesten van VIEWS niet verstandig is, daarom wou ik de query als 1 query gaan maken maar om ik zou dan 8 * 12 = 96 keer een UNION ALL moeten gebruiken. Dus graag een suggestie waarmee dit handiger en met name effici├źnter kan.

    Alvast bedankt.
    Last edited by Pascal G++; 11-Aug-17 at 14:34. Reason: wijziging

  2. #2
    Als ik het goed zie krijg je met deze maand-overzicht en unions een volgende resultaat:

    Code:
                             jan feb mrt apr mei jun
    fac en andere gegevens    X   0   0   0   0   0
    fac en andere gegevens    0   X   0   0   0   0
    fac en andere gegevens    0   0   X   0   0   0
    fac en andere gegevens    0   0   0   X   0   0
    fac en andere gegevens    0   0   0   0   X   0
    fac en andere gegevens    0   0   0   0   0   X
    etc

    Je kunt het echter ook zo doen dat je dit krijgt:

    Code:
                             jan feb mrt apr mei jun
    fac en andere gegevens    X   X   X   X   X   X
    In dat geval kun je de WHERE verplaatsen naar de SELECT-velden en met CASE of WHERE (afhankelijk van de DB) controleren op de maand en dan heb je geen 12 UNIONs nodig.

  3. #3
    Mijn voorkeur heeft jouw 2e optie.
    Ik heb al gestoeid met het verplaatsen van de WHERE naar de SELECT maar dan krijg ik niet meer de data van 1 klant maar van alle klanten per regel.
    DB is een MSSQL 2012.

    En moet de volledige WHERE dan verplaatst worden naar de SELECT? en krijg ik dus 12 keer een WHERE in de SELECT?

  4. #4
    Je kunt zoiets dergelijks doen:
    SQL Code:
    1. SELECT
    2.   Year(datum) AS Jaar,
    3.   sum(iif(month(datum) = 1, bedrag, 0)) AS jan,
    4.   sum(iif(month(datum) = 2, bedrag, 0)) AS feb,
    5.   sum(iif(month(datum) = 3, bedrag, 0)) AS mrt
    6. FROM data1
    7. GROUP BY Year(datum)
    Dus in de jan, feb enz. kolommen met sum() en daarbinnen met iif() controleren of de maand goed is. Zo ja, dan bedrag geven anders 0.

    Hier kun je een werkend voorbeeldje zien voor SQL server 2014.
    http://rextester.com/TTCVB41976

  5. #5
    rik je hebt mijn dag gemaakt.
    Alle views vervangen door 1 nieuwe query en de uitvoertijd is van 16 seconden terug naar 0,5 seconden gegaan.

    DANK!

  6. #6
    Daar doen we het voor

    Wat een beetje SQL-optimalisatie allemaal kan doen

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •