मेरा सुझाव है कि हम क्रमिक रूप से, चरण दर चरण क्वेरी का निर्माण करें। सत्यापित करें कि क्वेरी परिणाम वैसे ही हैं जैसे हम प्रत्येक चरण में अपेक्षा करते हैं। जब कुछ "काम नहीं करता", एक कदम का बैकअप लें।
हम तीन पंक्तियों को वापस करना चाहते हैं, प्रत्येक पंक्ति के लिए एक ___Segmentations
. में , एक विशिष्ट hotelid
. के लिए
SELECT r.seg_id
, r.seg_text
FROM ___Segmentations r
WHERE r.seg_hotelid = :hotel_id
ORDER BY r.seg_id
बाहरी जुड़ाव को __Bookings
. में जोड़ें
SELECT r.seg_id
, r.seg_text
, b.boo_id
FROM ___Segmentations r
LEFT
JOIN ___Bookings b
ON b.boo_segmentation = r.seg_id
WHERE r.seg_hotelid = :hotel_id
ORDER
BY r.seg_id
, b.boo_id
बाहरी जुड़ाव को ___BillableDatas
. में जोड़ें
SELECT r.seg_id
, r.seg_text
, b.boo_id
, d.bil_id
FROM ___Segmentations r
LEFT
JOIN ___Bookings b
ON b.boo_segmentation = r.seg_id
LEFT
JOIN `___BillableDatas` d
ON d.bil_bookingid = b.boo_id
WHERE r.seg_hotelid = :hotel_id
ORDER
BY r.seg_id
, b.boo_id
, d.bil_id
यदि यही वह पंक्तियाँ हैं जिनमें हमारी रुचि है, तो हम एकत्रीकरण पर काम कर सकते हैं।
SELECT 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.boo_segmentation = r.seg_id
LEFT
JOIN `___BillableDatas` d
ON d.bil_bookingid = b.boo_id
WHERE r.seg_hotelid = :hotel_id
GROUP
BY r.seg_id
, r.seg_text
ORDER
BY r.seg_text
अब "कुल" के साथ एकत्रीकरण प्राप्त करने के लिए।
क्रॉस जॉइन ऑपरेशन का उपयोग करके, मैं जो दृष्टिकोण लेता हूं वह पंक्तियों की "प्रतियां" बनाना होगा। हम इनलाइन व्यू के रूप में संदर्भित, हमारे द्वारा लिखी गई पहली क्वेरी द्वारा लौटाई गई पंक्तियों में शामिल हो सकते हैं। (q
. के रूप में उपनामित नीचे।)
यदि हमारे पास पंक्तियों का एक पूरा सेट है, तो प्रत्येक seg_id/seg_text
. के लिए दोहराया जाता है (वह पहली क्वेरी जो हमने लिखी थी), हम सशर्त एकत्रीकरण का उपयोग कर सकते हैं।
वह आखिरी क्वेरी जो हमने लिखी थी (ठीक ऊपर) नीचे दी गई क्वेरी में एक इनलाइन दृश्य है, जिसे c
के रूप में उपनामित किया गया है ।
cnt_bookings
. का योग सभी पंक्तियों में से कुल है।
अलग-अलग गणनाओं के लिए, हम केवल उन पंक्तियों को शामिल कर सकते हैं जिनका मिलान seg_id
. से होता है , उस सबसेट का कुल।
SELECT 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_hotelid = :hotel_id_1
ORDER BY t.seg_id
) q
CROSS
JOIN ( SELECT 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
ON b.boo_segmentation = r.seg_id
LEFT
JOIN `___BillableDatas` d
ON d.bil_bookingid = b.boo_id
WHERE r.seg_hotelid = :hotel_id
GROUP
BY r.seg_id
) c
GROUP
BY q.seg_id
, q.seg_text
ORDER
BY q.seg_text
SELECT
. में सूची, हम प्रतिशत प्राप्त करने के लिए विभाजन कर सकते हैं:cnt_bookings * 100.0 / tot_bookings
उदा.
SELECT 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
पंक्तियों को अपने इच्छित क्रम में वापस करने के लिए ORDER BY खंड को संशोधित करें
SELECT
. से निकालें उन भावों को सूचीबद्ध करें जो tot_bookings
return लौटाते हैं और tot_billable
.
संपादित करें
मुझे लगता है कि मैं तारीख मानदंड से चूक गया। हम बाहरी जॉइन को इनर जॉइन में बना सकते हैं, और क्रॉस जॉइन को लेफ्ट जॉइन से बदल सकते हैं। हमारे पास cnt_bookings
. के लिए NULL मान लौटाने की क्षमता है और cnt_billable
, हम NULL को शून्य से बदलने के लिए उन्हें IFNULL() या COALESCE() फ़ंक्शन में लपेट सकते हैं।
SELECT 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_text
FROM ___Segmentations t
WHERE t.seg_hotelid = :hotel_id_1
ORDER BY t.seg_id
) q
LEFT
JOIN ( SELECT r.seg_id
, COUNT(DISTINCT b.boo_id) AS cnt_bookings
, COUNT(DISTINCT d.bil_id) AS cnt_billable
FROM ___Segmentations r
JOIN ___Bookings b
ON b.boo_segmentation = r.seg_id
JOIN `___BillableDatas` d
ON d.bil_bookingid = b.boo_id
AND d.bil_date BETWEEN '2017-02-21' AND '2017-02-28'
WHERE r.seg_hotelid = :hotel_id
GROUP
BY r.seg_id
) c
ON 1=1
GROUP
BY q.seg_id
, q.seg_text
ORDER
BY q.seg_text