mysqlsqlcustomcolumn

SQL - Make a custom table with month based columns and year based rows


I am trying to make an awesome custom table which counts the amount of rows and organises them so that if there are three rows with a date in January 2013, four in March 2014 and five in October 2014 the table would show up as:

     Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
2013 3   0   0   0   0   0   0   0   0   0   0   0
2014 0   0   4   0   0   0   0   0   0   5   0   0

Solution

  • I would recommend using a view, rather than a new table, this way when your underlying data changes your new table won't be out of sync.

    Since you have not given much sample data I have had to assume a structure, but you would want something like this:

    CREATE TABLE T (`Date` DATETIME);
    INSERT T (`Date`)
    VALUES 
        ('2013-01-01'), ('2013-01-02'), ('2013-01-03'), 
        ('2014-03-01'), ('2014-03-02'), ('2014-03-03'),
        ('2014-10-01'), ('2014-10-01'), ('2014-10-01'),
        ('2014-10-01'), ('2014-10-01');
    
    CREATE VIEW V
    AS
        SELECT  YEAR(`Date`) AS `Year`,
                COUNT(CASE WHEN MONTH(`Date`) = 1 THEN 1 END) AS `Jan`,
                COUNT(CASE WHEN MONTH(`Date`) = 2 THEN 1 END) AS `Feb`,
                COUNT(CASE WHEN MONTH(`Date`) = 3 THEN 1 END) AS `Mar`,
                COUNT(CASE WHEN MONTH(`Date`) = 4 THEN 1 END) AS `Apr`,
                COUNT(CASE WHEN MONTH(`Date`) = 5 THEN 1 END) AS `May`,
                COUNT(CASE WHEN MONTH(`Date`) = 6 THEN 1 END) AS `Jun`,
                COUNT(CASE WHEN MONTH(`Date`) = 7 THEN 1 END) AS `Jul`,
                COUNT(CASE WHEN MONTH(`Date`) = 8 THEN 1 END) AS `Aug`,
                COUNT(CASE WHEN MONTH(`Date`) = 9 THEN 1 END) AS `Sep`,
                COUNT(CASE WHEN MONTH(`Date`) = 10 THEN 1 END) AS `Oct`,
                COUNT(CASE WHEN MONTH(`Date`) = 11 THEN 1 END) AS `Nov`,
                COUNT(CASE WHEN MONTH(`Date`) = 12 THEN 1 END) AS `Dec`
        FROM    T
        GROUP BY YEAR(`Date`);
    

    Example on SQL Fiddle