Home > Software design >  Concat/Union two tables in SQL
Concat/Union two tables in SQL

Time:05-31

The sql query below creates two tables, tab1 with 3 columns (quarter, region and datasum) and tab2 with 2 columns (quarter and datasum).

I want to stack the values from tab1 and tab2 together (just like pd.concat([tab1, tab2]) in pandas/python). For that I need to create a new column in tab2 called region and insert that in the same position as the corresponding column in tab1. And after that I think I need to use UNION_ALL.

In tab2 I would like the value of the column region to be 'all' for every instance.

How could I achieve this?

I tried to use ALTER TABLE and ADD but I don't get that to work for me. Help would be much appreciated. I work in SQL Oracle.

with base1 as(
    select substr(municip,1,2) as region, data, age,
            case when substr(time,6,2) in ('01','02','03') then substr(time, 1,4) || '_1'
                                when substr(time,6,2) in ('04','05','06') then substr(time, 1,4) || '_2'
                                when substr(time,6,2) in ('07','08','09') then substr(time, 1,4) || '_3' 
                                else substr(time, 1,4) || '_4' end quarter
        
                from sql_v1
                where time >= '2021-01' and
                ),
                  
base2 as(select data, age,
            case when substr(time,6,2) in ('01','02','03') then substr(time, 1,4) || '_1'
                                when substr(time,6,2) in ('04','05','06') then substr(time, 1,4) || '_2'
                                when substr(time,6,2) in ('07','08','09') then substr(time, 1,4) || '_3' 
                                else substr(time, 1,4) || '_4' end quarter 
                from sql_v1
                where time >= '2021-01'),       

tab1 as (select quarter, region,
    sum (case when age between '16' and '64' then kvar else 0 end) datasum 
    from base
    group by quarter, region
    order by quarter, region),
    
tab2 as (select quarter,
    sum (case when age between '16' and '64' then kvar else 0 end) datasum 
    from riket
    group by quarter
    order by quarter)

...select * from tab_union

CodePudding user response:

It appears that you're using strings for storing dates??? Don't do that :(

If you use native datetime datatypes then you can extract the quarter using things like TO_CHAR(datetime_column, 'Q')

For now, however, using the horrendous datatypes, you can restructure your query to use ROLLUP in your GROUP BY...

WITH
  formatted AS
(
  SELECT
    SUBSTR(municip,1,2)                                                                 AS region,
    SUBSTR(time, 1,4) || CASE WHEN SUBSTR(time,6,2) IN ('01','02','03') THEN '_1'
                              WHEN SUBSTR(time,6,2) IN ('04','05','06') THEN '_2'
                              WHEN SUBSTR(time,6,2) IN ('07','08','09') THEN '_3' 
                                                                        ELSE '_4' END   AS quarter,
    age,
    kvar
  FROM
    sql_v1
  WHERE
    time >= '2021-01'
)
SELECT
  region,
  COALESCE(quarter, 'All'),
  SUM(CASE WHEN age BETWEEN 16 AND 64 THEN kvar ELSE 0 END)
FROM
  formatted
GROUP BY
  region, ROLLUP(quarter)
ORDER BY
  region,
  GROUPING(quarter),
  quarter

Demo : https://dbfiddle.uk/?rdbms=oracle_21&fiddle=ab27d71ac81bb9bc7e5e06e7f5a44ba9

Or, using DATE datatype : https://dbfiddle.uk/?rdbms=oracle_21&fiddle=1544406dc2b6669bc62ed02a6155b1c2

  •  Tags:  
  • sql
  • Related