Search code examples
sybasesap-ase

How to Left Inner Join two queries in Sybase?


I have two queries that should be joined together. Here is my query 1:

SELECT
    t1.rec_id, 
    t1.category,
    t1.name, 
    t1.code,
    CASE 
        WHEN t1.name= 'A' THEN SUM(t1.amount)
        WHEN t1.name = 'D' THEN SUM(t1.amount)
        WHEN t1.name = 'H' THEN SUM(t1.amount)
        WHEN t1.name = 'J' THEN SUM(t1.amount)
    END AS Amount
FROM Table1 t1
GROUP BY t1.name, t1.rec_id, t1.category, t1.code

Query 1 produce this set of results:

Rec ID Category  Name   Code    Amount
1        1       A      MIX    70927.00
1        3       D      MIX    19922.00
1        2       H      MIX    55104.00
1        4       J      MIX    76938.00

Then I have query 2:

SELECT 
    CASE 
        WHEN t2.category_id = 1 THEN SUM(t2.sum)
        WHEN t2.category_id = 2 THEN SUM(t2.sum)
        WHEN t2.category_id = 3 THEN SUM(t2.sum)
        WHEN t2.category_id = 4 THEN SUM(t2.sum)
    END AS TotalSum
FROM Table2 t2
    INNER JOIN Table1 t1 
        ON t1.amnt_id = t2.amnt_id
        AND t2.unique_id = @unique_id
GROUP BY t2.category_id

The result set of query 2 is this:

TotalSum
186013.00
47875.00
12136.00
974602.00

All I need is this result set that combines query 1 and query 2:

Rec ID Category  Name   Code    Amount      TotalSum
    1        1       A      MIX    70927.00    186013.00
    1        3       D      MIX    19922.00    47875.00
    1        2       H      MIX    55104.00    12136.00
    1        4       J      MIX    76938.00    974602.00

As you can see there is connection between table 1 and table 2. That connection is amnt_id. However, I tried doing LEFT INNER JOIN on query 1 and then simply using same logic with case statement to get the total sum for table 2. Unfortunately Sybase version that I use does not support Left Inner Join. I'm wondering if there is other way to join these two queries? Thank you


Solution

  • I wondered if the CASE statement makes sense in the first query because it sums in every row. Are there other values for the name column except A, D, H, J? If not you can change the CASE statement to SUM(t1.amount) AS Amount. Also the GROUP BY in the first query seems dubious to me: you are grouping by the record id column - that means you are not grouping at all but instead return every row. If that is what you really want you can omit the SUM at all and just return the pure amount column.

    As far as I understood your problem and your data structure: the values in Table2 are kind of category sums and the values in Table1 are subsets. You would like to see the category sum for every category in Table1 next to the single amounts?

    You would typically use a CTE (common table expression, "WITH clause") but ASE doesn't support CTEs, so we have to work with joins. I recreated your tables in my SQL Anywhere database and put together this example. In a nutshell: both queries are subqueries in an outer query and are left joined on the category id:

    SELECT *
    FROM
    (
    SELECT
        t1.rec_id,
        t1.category,
        t1.name, 
        t1.code,
        CASE 
            WHEN t1.name= 'A' THEN SUM(t1.amount)
            WHEN t1.name = 'D' THEN SUM(t1.amount)
            WHEN t1.name = 'H' THEN SUM(t1.amount)
            WHEN t1.name = 'J' THEN SUM(t1.amount)
        END AS Amount
    FROM Table1 t1
    GROUP BY t1.rec_id, t1.name, t1.category, t1.code
    ) AS t1
    LEFT JOIN
    (
    SELECT category_id, SUM(sum) FROM
    table2
    GROUP BY category_id
    ) AS totals(category_id, total_sum)
    ON totals.category_id = t1.category;
    

    This query gives me:

    Rec ID  Category    Name    Code  Amount   Category_id  total_sum
    2       3              D     MIX  19922.00   3          47875.00
    3       2              H     MIX  55104.00   2          12136.00
    1       1              A     MIX  70927.00   1          186013.00
    4       4              J     MIX  76938.00   4          974602.00
    

    You surely have to tweak it a bit including your t2.unique_id column (that I don't understand from your queries) but this is a practical way to work around ASE's missing CTE feature.

    BTW: it's either an INNER JOIN (only the corresponding records from both tables) or a LEFT (OUTER) JOIN (all from the left, only the corresponding records from the right table) but a LEFT INNER JOIN makes no sense.