1

I would like help adding a UNION to get all the months to a query. I tried adding union in a bunch of spots but just can't get it right. enter image description here

SELECT MONTH(FirstPublishedToPortal) AS theMonth,
   YEAR(FirstPublishedToPortal) AS theYear,
   MONTHNAME(FirstPublishedToPortal) AS theMonthName,
   COUNT(DISTINCT PONum) AS POCount,

   SUM(unconfirmedEmailSent) AS unconfirmedEmailsSent,
   ( SELECT COUNT(DISTINCT PONum)
     FROM POFlags
     WHERE unconfirmedEmailSent = 0
     AND MONTH(FirstPublishedToPortal) = theMonth
     AND YEAR(FirstPublishedToPortal) = theYear
     AND VendorNum = '2222'
   ) AS onTimeConfirmed,

   SUM(lateEmailSent) AS lateEmailsSent,
   ( SELECT COUNT(DISTINCT PONum)
     FROM POFlags
     WHERE lateEmailSent = 0
     AND MONTH(FirstPublishedToPortal) = theMonth
     AND YEAR(FirstPublishedToPortal) = theYear
     AND VendorNum = '2222'
   ) AS onTimePOCount

FROM POFlags

WHERE VendorNum = '2222'
   AND FirstPublishedToPortal >= '2017-01-08'

GROUP BY theYear DESC, theMonth DESC
ORDER BY FirstPublishedToPortal DESC 

Where do the union clauses go in this query? I think there needs to be something like the following code but I don't understand where to put it to work correctly with the GROUP BY or ORDER BY.

(SELECT 1, null, 'January', 0, 0, 0, 0, 0)
UNION 
(SELECT 2, null, 'February', 0, 0, 0, 0, 0)
UNION 
(SELECT 3, null, 'March', 0, 0, 0, 0, 0)
.    
.
(SELECT 12, null, 'December, 0, 0, 0, 0, 0)

SQL FIDDLE HERE

1 Answer 1

2

Use a left join based on a nested query with union.

Use Coalesce to apply your default values.

Move where condition on join clause

warning, 2017 is hardcoded

Something like this : http://sqlfiddle.com/#!9/458808/27

SELECT
    all_month.nMonth AS theMonth, 
    coalesce(YEAR(FirstPublishedToPortal),2017) AS theYear,
    all_month.sMonth AS theMonthName,
    coalesce(COUNT(DISTINCT PONum),0) AS POCount,

    coalesce(SUM(unconfirmedEmailSent),0) AS unconfirmedEmailsSent,
    coalesce(( SELECT COUNT(DISTINCT PONum)
       FROM POFlags
       WHERE unconfirmedEmailSent = 0
         AND MONTH(FirstPublishedToPortal) = theMonth
         AND YEAR(FirstPublishedToPortal) = theYear
         AND VendorNum = '2222'
    ),0) AS onTimeConfirmed,

    coalesce(SUM(lateEmailSent),0) AS lateEmailsSent,
    coalesce(( SELECT COUNT(DISTINCT PONum)
       FROM POFlags
       WHERE lateEmailSent = 0
         AND MONTH(FirstPublishedToPortal) = theMonth
         AND YEAR(FirstPublishedToPortal) = theYear
         AND VendorNum = '2222'
     ),0) AS onTimePOCount
FROM (
     (SELECT 1 nMonth, 'January' sMonth)   UNION ALL
     (SELECT 2 nMonth, 'February' sMonth ) UNION ALL
     (SELECT 3 nMonth, 'March' sMonth )    UNION ALL
     (SELECT 4 nMonth, 'April' sMonth )    UNION ALL
     (SELECT 5 nMonth, 'May' sMonth )      UNION ALL
     (SELECT 6 nMonth, 'June' sMonth )     UNION ALL
     (SELECT 7 nMonth, 'July' sMonth )     UNION ALL
     (SELECT 8 nMonth, 'August' sMonth )   UNION ALL
     (SELECT 9 nMonth, 'September' sMonth) UNION ALL
     (SELECT 10 nMonth, 'October' sMonth ) UNION ALL
     (SELECT 11 nMonth, 'November' sMonth )UNION ALL    
     (SELECT 12 nMonth, 'December' sMonth)
     ) all_month left join POFlags on
         MONTH(FirstPublishedToPortal)=nMonth and
         VendorNum = '2222' and
         FirstPublishedToPortal >= '2017-01-08'
GROUP BY
    theYear DESC, nMonth DESC
ORDER BY
    nMonth DESC 

Another way exist using a global union between your orginal result and the default value, but this method require a second group by...

Sign up to request clarification or add additional context in comments.

3 Comments

This works wonderfully. I had trouble understanding where to put the UNION selects. And using COALESCE for default values--I never thought of that! Since I can build this query at run time, I can pass the year based on some parameter passed to my PHP script-- so no problem there. Thank you!
How I solved the default hardcoded year problem since I only needed one year's worth of data and had some variables available in my script: COALESCE(YEAR(FirstPublishedToPortal), IF(nMonth > " . $cutoff_month . ", " . $prev_year . ", " . $cutoff_year . ") ) AS theYear,
Using PHP, it's a simple solution ;-). With SQL only it's a little more complexe.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.