Reputation: 51
I've made schema changes/improvements to a table, but I need to ensure that I don't lose any existing data and it is 'migrated' across to the new schema and conforms to its design.
The existing schema is designed as follows:
ID FK_ID ShowChartX ShowChartY ShowChartZ
-- ----- ---------- ---------- ----------
1 2 1 0 1
The columns of ShowChartX, ShowChartY, and ShowChartZ are of type BIT (boolean).
I've now created a standalone table that keeps a record/reference of each chart. Each Chart record has a Chart_ID - the aim here is to use an ID for each type of chart instead of horizontally scaling a 'ShowChart' column for each type of chart going forward. Essentially, I would like to map all columns of 'ShowChart' to their actual Chart_ID key in the table I mention below:
The new schema would look like this:
ID FK_ID Chart_ID
-- ----- --------
1 2 1
2 2 2
I've started looking at Pivot/Unpivot, but I'm not sure if it's the correct operation. Could anyone please point me in the right direction here? Thanks in advance!
Upvotes: 0
Views: 232
Reputation: 12959
Thanks to @gotqn for the table definition and values.
The same result can be achieved using CROSS APPLY. Here, I am deriving Chart_Id based on ChartType, as I don't have the table reference for ChartTypes. Ideally, You can join with ChartTypes to get the corresponding Chart_Id.
DECLARE @DataSource TABLE
(
[ID] INT
,[FK_ID] INT
,[ShowChartX] BIT
,[ShowChartY] BIT
,[ShowChartZ] BIT
);
INSERT INTO @DataSource ([ID], [FK_ID], [ShowChartX], [ShowChartY], [ShowChartZ])
VALUES (1, 2, 1, 0, 1);
SELECT id,
fk_id,
CASE charttype
WHEN 'ChartX' THEN 1
WHEN 'ChartY' THEN 3
WHEN 'ChartZ' THEN 2
END AS Chart_ID
FROM @DataSource
CROSS apply (VALUES('ChartX', showchartx),
('ChartY', showcharty),
('ChartZ', showchartz)) AS t(charttype, isavailable)
WHERE isavailable <> 0;
Result set
+----+-------+----------+
| ID | FK_ID | Chart_ID |
+----+-------+----------+
| 1 | 2 | 1 |
| 1 | 2 | 2 |
+----+-------+----------+
Upvotes: 2
Reputation: 43636
This will UNPIVOT
the data. You can also, join the charts
table by name in order to get the chart_id
and check for differences with the new table:
DECLARE @DataSource TABLE
(
[ID] INT
,[FK_ID] INT
,[ShowChartX] BIT
,[ShowChartY] BIT
,[ShowChartZ] BIT
);
INSERT INTO @DataSource ([ID], [FK_ID], [ShowChartX], [ShowChartY], [ShowChartZ])
VALUES (1, 2, 1, 0, 1);
SELECT [ID]
,[FK_ID]
,[column] AS [chart_name]
FROM @DataSource DS
UNPIVOT
(
[value] FOR [column] IN ([ShowChartX], [ShowChartY], [ShowChartZ])
) UNPVT
WHERE [value] = 1;
For checking for differences it's pretty easy to use EXCEPT - for example:
SELECT *
FROM T1
EXCEPT
SELECT *
FROM T2;
to get records that are not including in T2
but in T1
and then the reverse:
SELECT *
FROM T2
EXCEPT
SELECT *
FROM T1;
Upvotes: 2