Skip to content
Advertisement

SQL compare rows between groups and show the missing

I have the following data from a SQL DB. There are 98 columns in total this is an extract of 4 to illustrate what I would like to to and in the final query I would expect to require 51 of them. There are 15 million rows to this table.

+-----------------+-----------------+---------------------+------------------------------+
|    RatePlan     | RatePlanCharge  | SubscriptionVersion | RatePlanChargePreDiscountMRR |
+-----------------+-----------------+---------------------+------------------------------+
|                 |                 |                     |                              |
| Main Product    | Main Product    | 7                   | 90                           |
|                 |                 |                     |                              |
| Online Support  | Online Support  | 7                   | 0                            |
|                 |                 |                     |                              |
| Module Support  | Module Support  | 7                   | 0                            |
|                 |                 |                     |                              |
| Main Product    | Main Product    | 6                   | 90                           |
|                 |                 |                     |                              |
| Module Support  | Module Support  | 6                   | 0                            |
|                 |                 |                     |                              |
| Main Product    | Main Product    | 5                   | 90                           |
|                 |                 |                     |                              |
| Premium Support | Premium Support | 5                   | 40                           |
|                 |                 |                     |                              |
| Module Support  | Module Support  | 5                   | 0                            |
|                 |                 |                     |                              |
| Main Product    | Main Product    | 4                   | 90                           |
|                 |                 |                     |                              |
| Module Support  | Module Support  | 4                   | 0                            |
|                 |                 |                     |                              |
| Main Product    | Main Product    | 3                   | 90                           |
|                 |                 |                     |                              |
| Online Support  | Online Support  | 3                   | 0                            |
|                 |                 |                     |                              |
| Module Support  | Module Support  | 3                   | 0                            |
|                 |                 |                     |                              |
| Main Product    | Main Product    | 2                   | 90                           |
|                 |                 |                     |                              |
| Online Support  | Online Support  | 2                   | 0                            |
|                 |                 |                     |                              |
| Main Product    | Main Product    | 1                   | 85                           |
|                 |                 |                     |                              |
| Online Support  | Online Support  | 1                   | 0                            |
+-----------------+-----------------+---------------------+------------------------------+

This table shows each change to a subscription. We can see;

  • At version 3 Module Support is added
  • At version 4 Online Support is removed
  • At version 5 Premium Support is added
  • At version 6 Premium Support is removed
  • At version 7 Online Support is added

What I want to do is run a query that will return rows missing from the current version that were present in the previous version, as below.

+-----------------+-----------------+---------------------+------------------------------+--------------------------------+
|    RATEPLAN     | RATEPLANCHARGE  | SUBSCRIPTIONVERSION | RATEPLANCHARGEPREDISCOUNTMRR |  SUBSCRIPTIONVERSION_MISSINGFROM |
+-----------------+-----------------+---------------------+------------------------------+--------------------------------+
|                 |                 |                     |                              |                                |
| Premium Support | Premium Support | 5                   | 40                           | 6                              |
|                 |                 |                     |                              |                                |
| Online Support  | Online Support  | 3                   | 0                            | 4                              |
+-----------------+-----------------+---------------------+------------------------------+--------------------------------+

Is this possible?

Advertisement

Answer

SELECT n.RatePlan, n.SubscriptionVersion,
    CASE 
        WHEN c.RatePlan IS NOT NULL AND p.RatePlan IS NOT NULL THEN 'Continued' 
        WHEN c.RatePlan IS     NULL AND p.RatePlan IS NOT NULL THEN 'Discontinued'
        WHEN c.RatePlan IS NOT NULL AND p.RatePlan IS     NULL THEN 'New'
        ELSE '!' END AS Status,
FROM (
    -- The labels we need are everything in the current and previous version.
    SELECT DISTINCT RatePlan, SubscriptionVersion
    FROM (
        -- Plans in the current verson.
        SELECT RatePlan, SubscriptionVersion FROM WhateverItIs
        UNION
        -- Plans in the previous version.
        SELECT p.RatePlan, w.SubscriptionVersion
        FROM WhateverItIs w
            INNER JOIN WhateverItIs p ON p.SubscriptionVersion + 1 = w.SubscriptionVersion
    ) T
) AS n
    LEFT JOIN WhateverItIs c ON n.RatePlan = c.RatePlan AND n.SubscriptionVersion = c.SubscriptionVersion -- Is it current?
    LEFT JOIN WhateverItIs p ON n.RatePlan = p.RatePlan AND n.SubscriptionVersion = p.SubscriptionVersion + 1 -- Is it previous?

I don’t generally think of FULL OUTER JOIN, but indeed that works too.

SELECT ISNULL(c.RatePlan, p.RatePlan) AS RatePlan,
    ISNULL(c.SubscriptionVersion, p.SubscriptionVersion + 1) AS SubscriptionVersion,
    CASE 
        WHEN c.RatePlan IS NOT NULL AND p.RatePlan IS NOT NULL THEN 'Continued' 
        WHEN c.RatePlan IS     NULL AND p.RatePlan IS NOT NULL THEN 'Discontinued'
        WHEN c.RatePlan IS NOT NULL AND p.RatePlan IS     NULL THEN 'New'
        ELSE '!' 
    END AS Status,
FROM WhateverItIs c
    FULL OUTER JOIN WhateverItIs p ON c.RatePlan = p.RatePlan AND c.SubscriptionVersion = p.SubscriptionVersion + 1
User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement