Search code examples
mysqlaggregaterollup

How do I use ROLLUP to create a super aggregate for only one column in mysql?


I have the following tables:

CREATE TABLE IF NOT EXISTS Business (
    Ticker        VARCHAR(255) NOT NULL UNIQUE,
    Company_Name  VARCHAR(255) NOT NULL UNIQUE,
    Currency      CHAR(3) NOT NULL,
    Portfolio     VARCHAR(255) NOT NULL,
    PRIMARY KEY ( Company_Name ),
    FOREIGN KEY ( Currency ) REFERENCES Currency ( Currency_Code ) ON UPDATE CASCADE ON DELETE CASCADE,
    FOREIGN KEY ( Portfolio ) REFERENCES Portfolio ( Portfolio_Name ) ON UPDATE CASCADE ON DELETE RESTRICT,
    CONSTRAINT CHK_Ticker CHECK ( Ticker = UPPER( Ticker ) )
);

CREATE TABLE IF NOT EXISTS Dividend (
    Dividend_ID           INTEGER NOT NULL UNIQUE AUTO_INCREMENT,
    Ticker             VARCHAR(255) NOT NULL,
    Dividend_Date         DATE NOT NULL,
    Dividend_Amount                 DOUBLE NOT NULL,
    SGD_XR                   DOUBLE NOT NULL,
    PRIMARY KEY ( Dividend_ID ),
    FOREIGN KEY ( Ticker ) REFERENCES Business ( Ticker ) ON UPDATE CASCADE ON DELETE CASCADE,
    CONSTRAINT CHK_SGD_XR CHECK ( SGD_XR >= 0 )
);

And I want to use these tables for the following Select:

SELECT
        IFNULL( Business.Company_Name,'Total Year To Date Dividends (SGD)' ) AS Company_Name,
        SUM(
            CASE WHEN Dividend.Dividend_Date >= STR_TO_DATE( CONCAT( '1 January ', YEAR(CURDATE()) ), '%d %M %Y' ) AND Dividend.Dividend_Date <= CURDATE() 
            THEN Dividend.Dividend_Amount 
            END) AS Year_To_Date_Dividends,
        SUM(
            CASE WHEN Dividend.Dividend_Date >= STR_TO_DATE( CONCAT( '1 January ', YEAR(CURDATE()) ), '%d %M %Y' ) AND Dividend.Dividend_Date <= CURDATE() 
            THEN Dividend.Dividend_Amount / Dividend.SGD_XR 
            END) AS SGD_Year_To_Date_Dividends
    FROM Business
    LEFT JOIN Dividend
        ON Business.Ticker = Dividend.Ticker
    GROUP BY Business.Company_Name WITH ROLLUP 

The issue here is that for my "Total Year To Date Dividends (SGD)" row which should be created by the Rollup, I only want it to calculate the sum of the SGD_Year_To_Date_Dividends column, not the Year_To_Date_Dividends column (since they all be in different currencies and so adding them makes no sense). I'm not sure how to specify the rollup to only aggregate the SGD_Year_To_Date_Dividends column (and put a null value in Year_To_Date_Dividends). How would I do this?


Solution

  • Instead of:

        SUM(
            CASE WHEN Dividend.Dividend_Date >= STR_TO_DATE( CONCAT( '1 January ', YEAR(CURDATE()) ), '%d %M %Y' ) AND Dividend.Dividend_Date <= CURDATE() 
            THEN Dividend.Dividend_Amount 
            END) AS Year_To_Date_Dividends,
    

    you would do:

        IF(Business.Company_Name IS NULL,'',SUM(
            CASE WHEN Dividend.Dividend_Date >= STR_TO_DATE( CONCAT( '1 January ', YEAR(CURDATE()) ), '%d %M %Y' ) AND Dividend.Dividend_Date <= CURDATE() 
            THEN Dividend.Dividend_Amount 
            END)) AS Year_To_Date_Dividends,
    

    For your SGD_Year_To_Date_Dividends, I suspect you want:

    ROUND(Dividend.Dividend_Amount / Dividend.SGD_XR,2)
    

    in place of

    Dividend.Dividend_Amount / Dividend.SGD_XR