Jeg foreslår, at vi bygger forespørgslen trinvist, trin for trin. Bekræft, at forespørgselsresultaterne er, som vi forventer på hvert trin. Når noget "ikke virker", tag backup af et trin.
Vi ønsker at returnere tre rækker, en for hver række i ___Segmentations
, for et specifikt hotelid
VÆLG r.seg_id , r.seg_text FRA ___Segmentations r HVOR r.seg_hotelid =:hotel_id BESTILLE EFTER r.seg_id
Tilføj den ydre forbindelse til __Bookings
VÆLG r.seg_id , r.seg_text , b.boo_id FROM ___Segmentations r LEFT JOIN ___Bookings b PÅ b.boo_segmentation =r.seg_id HVOR r.seg_hotelid =:hotel_id ORDER BY r.boid_
Tilføj den ydre joinforbindelse til ___BillableDatas
VÆLG r.seg_id , r.seg_text , b.boo_id , d.bil_id FRA ___Segmentations r LEFT JOIN ___Bookings b PÅ b.boo_segmentation =r.seg_id LEFT JOIN `___BillableDatas` b._d ON d. boo_id HVOR r.seg_hotelid =:hotel_id BESTIL EFTER r.seg_id , b.boo_id , d.bil_id
Hvis det er de rækker, vi er interesserede i, kan vi arbejde på aggregering.
VÆLG r.seg_id , r.seg_text , COUNT(DISTINCT b.boo_id) AS cnt_bookings , COUNT(DISTINCT d.bil_id) AS cnt_billable FROM ___Segmentations r LEFT JOIN ___Bookings b ON b.booFTs segmentation ON b.booFTs JOIN `___BillableDatas` d PÅ d.bil_bookingid =b.boo_id HVOR r.seg_hotelid =:hotel_id GROUP BY r.seg_id , r.seg_text BESTILLE BY r.seg_text
Nu for at få aggregeringen med "total".
Den tilgang, jeg ville tage, ville være at lave "kopier" af rækkerne ved at bruge en CROSS JOIN-operation. Vi kan sammenføje de rækker, der returneres af den allerførste forespørgsel, vi skrev, refereret til som en inline-visning. (Aliaseret som q
nedenfor.)
Hvis vi har et komplet sæt rækker, gentaget for hver seg_id/seg_text
(den første forespørgsel, vi skrev), kan vi bruge betinget aggregering.
Den sidste forespørgsel, vi skrev (lige ovenfor), er en indlejret visning i forespørgslen nedenfor, kaldet c
.
SUM af cnt_bookings
fra alle rækkerne er totalen.
For de individuelle optællinger kan vi kun inkludere de rækker, der har et matchende seg_id
, i alt den delmængde.
VÆLG q.seg_id , q.seg_text , SUM(IF(c.seg_id=q.seg_id,c.cnt_bookings,0)) AS cnt_bookings , SUM(c.cnt_bookings) AS tot_bookings , SUM(IF( c.seg_id=q.seg_id,c.cnt_billable,0)) AS cnt_billable , SUM(c.cnt_billable) AS tot_billable FROM ( SELECT t.seg_id , t.seg_text FROM ___Segmentations t WHERE t.seg_DER BY_1 =.thotel_hotelid_1 seg_id ) q CROSS JOIN ( VÆLG r.seg_id , COUNT(DISTINCT b.boo_id) AS cnt_bookings , COUNT(DISTINCT d.bil_id) AS cnt_billable FROM ___Segmentations r LEFT JOIN ___Bookings b.boo_id. d PÅ d.bil_bookingid =b.boo_id HVOR r.seg_hotelid =:hotel_id GRUPPER EFTER r.seg_id ) c GRUPPER EFTER q.seg_id , q.seg_text BESTILLING AF q.seg_text
I SELECT
liste, kan vi foretage opdelingen for at få procentdelen:cnt_bookings * 100.0 / tot_bookings
f.eks.
VÆLG q.seg_id , q.seg_text , SUM(IF(c.seg_id=q.seg_id,c.cnt_bookings,0)) AS cnt_bookings , SUM(c.cnt_bookings) AS tot_bookings , SUM(IF( c.seg_id=q.seg_id,c.cnt_bookings,0)) * 100,0 / SUM(c.cnt_bookings) AS pct_bookings , SUM(IF(c.seg_id=q.seg_id,c.cnt_billable,0)) AS cnt_billable , SUM (c.cnt_billable) AS tot_billable , SUM(IF(c.seg_id=q.seg_id,c.cnt_billable,0)) * 100,0 / SUM(c.cnt_billable) AS pct_billable
Rediger ORDER BY-sætningen for at returnere rækkerne i den rækkefølge, du ønsker
Fjern fra SELECT
liste de udtryk, der returnerer tot_bookings
og tot_billable
.
REDIGER
Jeg tror, jeg gik glip af datokriteriet. Vi kan lave de ydre sammenføjninger til indre sammenføjninger og erstatte CROSS JOIN med en LEFT JOIN. Vi har potentiale til at returnere NULL-værdier for cnt_bookings
og cnt_billable
, kan vi indpakke dem i IFNULL()- eller COALESCE()-funktionen for at erstatte NULL med nul.
VÆLG q.seg_id , q.seg_text , SUM(IF(c.seg_id=q.seg_id,c.cnt_bookings,0)) AS cnt_bookings , SUM(c.cnt_bookings) AS tot_bookings , SUM(IF( c.seg_id=q.seg_id,c.cnt_bookings,0)) * 100,0 / SUM(c.cnt_bookings) AS pct_bookings , SUM(IF(c.seg_id=q.seg_id,c.cnt_billable,0)) AS cnt_billable , SUM (c.cnt_billable) AS tot_billable , SUM(IF(c.seg_id=q.seg_id,c.cnt_billable,0)) * 100.0 / SUM(c.cnt_billable) AS pct_billable FROM ( SELECT t.seg_id , t.seg_Segmentations ROM t HVOR t.seg_hotelid =:hotel_id_1 BESTILLE EFTER t.seg_id ) q LEFT JOIN ( VÆLG r.seg_id , COUNT(DISTINCT b.boo_id) AS cnt_bookings , COUNT(DISTINCT d.bil_id) AS cnt_billableegmentations __JOIN. .boo_segmentation =r.seg_id JOIN ` ___BillableDatas` d PÅ d.bil_bookingid =b.boo_id OG d.bil_date MELLEM '2017-02-21' OG '2017-02-28' HVOR r.seg_hotelid =:hotel_id GROUP BY r.seg_id ) c ON 1=1 GROUP AF q.seg_id , q.seg_text BESTIL EFTER q.seg_text