I have the next two tables:
Table A
Product | Plant | ProductionWeek1 | ... | ProductionWeek11 |
---|---|---|---|---|
10011 | ABC32 | 6742 | ... | 3645 |
10011 | DEF10 | 3579 | ... | 8761 |
45891 | GHI22 | 8945 | ... | 1556 |
Table B
Product | Plant | SalesWeek1 | ... | SalesWeek11 |
---|---|---|---|---|
10011 | ABC32 | 425 | ... | 364 |
10011 | DEF10 | 879 | ... | 501 |
45891 | GHI22 | 904 | ... | 395 |
I would want a table like this, when the first week start in 01/01/2001, the second week would be 08/01/2001 ans so on, it could be any date the important thing is that the difference between dates have to be one week:
Product | Plant | Production | Sales | Date |
---|---|---|---|---|
10011 | ABC32 | 6742 | 425 | 01/01/2001 |
10011 | ABC32 | ... | ... | ... |
10011 | ABC32 | 3645 | 364 | 18/06/2001 |
10011 | DEF10 | 3579 | 879 | 01/01/2001 |
10011 | DEF10 | ... | ... | ... |
10011 | DEF10 | 8761 | 501 | 18/06/2001 |
45891 | GHI22 | 8945 | 904 | 01/01/2001 |
45891 | GHI22 | ... | ... | ... |
45891 | GHI22 | 1556 | 395 | 18/06/2001 |
I try the next code to transpose the columns for the two columns:
CREATE TABLE TABLE_A1 AS (SELECT P.PRODUCT AS PRODUCT_1,
P.PLANT AS PLANT_1,
P.PRODUCTION AS PRODUCTION_1
FROM (SELECT PRODUCT, PLANT, ProductionWeek1 FROM TableA
UNION
SELECT PRODUCT, PLANT, ProductionWeek2 FROM TableA
UNION
...
SELECT PRODUCT, PLANT, ProductionWeek11 FROM TableA) p;
CREATE TABLE TABLE_B1 AS (SELECT s.PRODUCT AS PRODUCT_2,
s.PLANT AS PLANT_2,
s.SALES AS SALES_2
FROM (SELECT PRODUCT, PLANT, SalesWeek1 FROM TableB
UNION
SELECT PRODUCT, PLANT, SalesWeek2 FROM TableB
UNION
...
SELECT PRODUCT, PLANT, SalesWeek11 FROM TableB) s;
Then try to put all together
CREATE TABLE FINAL_TABLE AS (
SELECT PRODUCT_1 AS PRODUCT,
PLANT_1_CONSUMOS AS PLANT,
PRODUCTION_1,
SALES_2
FROM TABLE_A1
INNER JOIN TABLE_B1
ON TABLE_B1.PRODUCT_2=TABLE_A1.PRODUCT_1
);
But I have a table like this:
Product | Plant | Production | Sales |
---|---|---|---|
10011 | ABC32 | 6742 | 425 |
10011 | ABC32 | 3645 | 425 |
10011 | ABC32 | 3645 | 364 |
The table is in disorder due to in the creation from TABLE_A1 and TABLE_B1 the union was in disorder too, so for that reason is important the date, for example I expect an union like this:
Product | Plant | Production | Sales |
---|---|---|---|
10011 | ABC32 | 6742 | 425 |
10011 | ABC32 | ... | ... |
10011 | ABC32 | 3645 | 364 |
But I got the next table
Product | Plant | Production | Sales |
---|---|---|---|
10011 | ABC32 | 3645 | 364 |
10011 | ABC32 | ... | ... |
10011 | ABC32 | 6742 | 425 |
where the value for the last week is in other row (not necesarry the first). Any help?
The current tables can be described as being "pivoted" because you have data representing a single week per column. To make sense of this you first need to "unpivot" that data and while you can use unions to do this, it is more efficient to simply cross join the source table to a set of rows representing each week (i.e. 11 rows). Then once cross joined use case expressions to move the data into the needed number of columns. e.g. the unpivoted result should look like this (ignoring weeks 2 to 10):
product plant week type value
10011 ABC32 1 production 6742
10011 DEF10 1 production 3579
45891 GHI22 1 production 8945
10011 ABC32 11 production 3645
10011 DEF10 11 production 8761
45891 GHI22 11 production 1556
10011 ABC32 1 sales 425
10011 DEF10 1 sales 879
45891 GHI22 1 sales 904
10011 ABC32 11 sales 364
10011 DEF10 11 sales 501
45891 GHI22 11 sales 395
Once the data is available in this form it is a relatively simple task to produce a combination of the source columns by week. Note also that in the 11 weekly rows to be used it is also possible to supply the needed dates.
nb as you have not specified which rdbms is being used the following is in Postgres syntax but aside from the ::date
syntax used the rest is generic SQL.
with w as (
select 1 as week, '2001-01-01'::date as week_date union all
/* other weeks */
select 11 as week, '2001-06-18'::date as week_date
)
, unpiv as (
select t.Product, t.Plant, w.week, w.week_date, 'production' as type
, case
when w.week = 1 then t.ProductionWeek1
/* Other weeks */
when w.week = 11 then t.ProductionWeek11
end as value
from Production t
cross join w
union all
select t.Product, t.Plant, w.week, w.week_dat, 'sales' as type
, case
when w.week = 1 then t.SalesWeek1
/* Other weeks */
when w.week = 11 then t.SalesWeek11
end as value
from Sales t
cross join w
)
select
u.Product, u.Plant
, max(case when type = 'production' then value end) as production
, max(case when type = 'sales' then value end) as sales
, week, week_date
from unpiv u
group by
u.Product, u.Plant
, week, week_date
order by
u.Product, u.Plant
, week, week_date
product | plant | production | sales | week | week_date |
---|---|---|---|---|---|
10011 | ABC32 | 6742 | 425 | 1 | 2001-01-01 |
10011 | ABC32 | 3645 | 364 | 11 | 2001-06-18 |
10011 | DEF10 | 3579 | 879 | 1 | 2001-01-01 |
10011 | DEF10 | 8761 | 501 | 11 | 2001-06-18 |
45891 | GHI22 | 8945 | 904 | 1 | 2001-01-01 |
45891 | GHI22 | 1556 | 395 | 11 | 2001-06-18 |
and here is a second (only slightly different) approach: https://dbfiddle.uk/pC0wmedZ