SQLize Online / PHPize Online  /  SQLtest Online

A A A
Share      Blog   Popular
Copy Format Clear
DROP TABLE IF EXISTS Tbl1; CREATE TABLE Tbl1 (T1F0 varchar(5), T1F1 varchar(5)); INSERT INTO Tbl1 (T1F0, T1F1) VALUES ('a','c'); INSERT INTO Tbl1 (T1F0, T1F1) VALUES ('c','d'); INSERT INTO Tbl1 (T1F0, T1F1) VALUES ('a','e'); DROP TABLE IF EXISTS Tbl2; CREATE TABLE Tbl2 (T2F0 varchar(5), T2F1 varchar(5), T2F2 varchar(5)); INSERT INTO Tbl2 (T2F0, T2F1, T2F2) VALUES ('X','U','P'); INSERT INTO Tbl2 (T2F0, T2F1, T2F2) VALUES ('X','V','Q'); INSERT INTO Tbl2 (T2F0, T2F1, T2F2) VALUES ('Y','V','R'); INSERT INTO Tbl2 (T2F0, T2F1, T2F2) VALUES ('Z','U','R'); DROP TABLE IF EXISTS Table1x2; CREATE TABLE Table1x2 AS SELECT * FROM Tbl1 CROSS JOIN Tbl2; DROP TABLE IF EXISTS Table1x2x1x2x1x2; CREATE TABLE Table1x2x1x2x1x2 (t11 varchar(5), t12 varchar(5), t13 varchar(5), t14 varchar(5), t15 varchar(5) ,t21 varchar(5), t22 varchar(5), t23 varchar(5), t24 varchar(5), t25 varchar(5) ,t31 varchar(5), t32 varchar(5), t33 varchar(5), t34 varchar(5), t35 varchar(5)); INSERT INTO Table1x2x1x2x1x2 SELECT T1.T1F0 AS t11, T1.T1F1 AS t12, T1.T2F0 AS t13, T1.T2F1 AS t14, T1.T2F2 AS t15 , T2.T1F0 AS t21, T2.T1F1 AS t22, T2.T2F0 AS t23, T2.T2F1 AS t24, T2.T2F2 AS t25 , T3.T1F0 AS t31, T3.T1F1 AS t32, T3.T2F0 AS t33, T3.T2F1 AS t34, T3.T2F2 AS t35 FROM Table1x2 AS T1, Table1x2 AS T2, Table1x2 AS T3; DO $$ BEGIN IF EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'Table1x2x1x2x1x2') THEN EXECUTE format('SELECT %L', 'Table1x2x1x2x1x2'); ELSE EXECUTE format('SELECT %L', 'Table1x2'); END IF; END $$; DO $$ DECLARE TableName TEXT := 'Table1x2x1x2x1x2'; Query TEXT; FirstName TEXT; BEGIN -- Take an arbitrary column (@FirstName) from the decomposed table (@TableName) Query := 'SELECT sysTbl.COLUMN_NAME ' || ' FROM INFORMATION_SCHEMA.COLUMNS sysTbl ' || ' WHERE sysTbl.TABLE_NAME = ''' || TableName || ''' ' || ' LIMIT 1'; EXECUTE Query INTO FirstName; END $$; --Take an arbitrary value (@FirstValue) from the column @FirstName. --It plays a role of the sorting variable with respect to which "evaluation to 0" and "derivation" are done. DO $$ DECLARE TableName text := 'Table1x2x1x2x1x2'; FirstName text; FirstValue text; BEGIN IF EXISTS (SELECT * FROM information_schema.tables WHERE table_name = TableName) THEN FirstName := (SELECT column_name FROM information_schema.columns WHERE table_name = TableName LIMIT 1); ELSE TableName := 'Table1x2'; FirstName := (SELECT column_name FROM information_schema.columns WHERE table_name = TableName LIMIT 1); END IF; EXECUTE 'SELECT ' || quote_ident(FirstName) || ' FROM ' || quote_ident(TableName) || ' ORDER BY ' || quote_ident(FirstName) || ' LIMIT 1' INTO FirstValue; END $$; --Compose attribute names for an intermediate table --that is a processed product of "derivation" and "evaluation to 0". DO $$ DECLARE TableName TEXT; Query TEXT; FirstName TEXT; FirstValue TEXT; Columns TEXT; BEGIN SELECT table_name INTO TableName FROM information_schema.tables WHERE table_name = 'Table1x2x1x2x1x2'; IF TableName IS NULL THEN TableName := 'Table1x2'; END IF; --Take an arbitrary column (@FirstName) from the decomposed table (@TableName) Query := 'SELECT column_name FROM information_schema.columns WHERE table_name = ''' || TableName || ''' LIMIT 1'; EXECUTE Query INTO FirstName; --Take an arbitrary value (@FirstValue) from the column @FirstName. --It plays a role of the sorting variable with respect to which "evaluation to 0" and "derivation" are done. Query := 'SELECT ' || quote_ident(FirstName) || ' FROM ' || quote_ident(TableName) || ' ORDER BY ' || quote_ident(FirstName) || ' LIMIT 1'; EXECUTE Query INTO FirstValue; --Generate the dynamic columns based on the table Query := 'SELECT string_agg(''D.'' || quote_ident(column_name) || '' AS D_'' || quote_ident(column_name) || '',E.'' || quote_ident(column_name) || '' AS E_'' || quote_ident(column_name), '''') FROM information_schema.columns WHERE table_name = ''' || TableName || ''' AND column_name != ''' || FirstName || ''''; EXECUTE Query INTO Columns; Query := 'SELECT ' || quote_literal(Columns) || ' || ''FROM (SELECT *, CASE WHEN ' || quote_ident(FirstName) || ' = ' || quote_literal(FirstValue) || ' THEN 0 ELSE (LEAD(' || quote_ident(FirstName) || ') OVER (ORDER BY ' || quote_ident(FirstName) || ') - ' || quote_ident(FirstName) || ')::FLOAT / NULLIF(' || quote_ident(FirstName) || ',0) END AS Diff FROM ' || quote_ident(TableName) || ') AS t UNPIVOT ( Val FOR Col IN (' || Columns || ') ) AS u PIVOT ( MAX(Val) FOR Type IN (D, E) ) AS p ORDER BY Col, Type DESC'; RAISE NOTICE 'Query: %', Query; END; $$ --Compose condition to remove duplicate rows that do not affect to decision making: --no difference by origin (D or E) for values in a attribute pair DO $$ DECLARE Duplicates TEXT; Query TEXT; BEGIN SELECT string_agg('AND((T.D_' || column_name || '=R.D_' || column_name || ' AND ' || 'T.E_' || column_name || '=R.E_' || column_name || ') OR ' || '(T.D_' || column_name || '=R.E_' || column_name || ' AND ' || 'T.E_' || column_name || '=R.D_' || column_name || '))', '') INTO Duplicates FROM information_schema.columns WHERE table_name = 'TableName' AND column_name != 'FirstName'; Query := 'SELECT ' || Duplicates || ' FROM intermediate_table T JOIN intermediate_table R ON T.rowid <> R.rowid'; RAISE NOTICE '%', Query; --EXECUTE Query; -- Uncomment this line to execute the query END $$; --Compose attribute computations emulating differentiation with respect to a variable over F2 DO $$ DECLARE Derivats TEXT; BEGIN EXECUTE 'SELECT string_agg(''IIF(T.D_'' || COLUMN_NAME || ''=V.D_'' || COLUMN_NAME || '',1,0) ^ ' || 'IIF(T.E_'' || COLUMN_NAME || ''=V.D_'' || COLUMN_NAME || '',1,0) AS ' || COLUMN_NAME || ', '''')' || ' FROM INFORMATION_SCHEMA.COLUMNS' || ' WHERE TABLE_NAME = ''' || TableName || '''' || ' AND COLUMN_NAME != ''' || FirstName || '''' INTO Derivats; Derivats := SUBSTRING(Derivats FROM 2); END $$; --Create bit attribute definition for the decision table DECLARE BitColumns TEXT; BEGIN SELECT STRING_AGG(COLUMN_NAME || ' BIT', ',') INTO BitColumns FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = TableName AND COLUMN_NAME <> FirstName; RETURN BitColumns; END; --Create DecisonTable. DROP TABLE IF EXISTS DecisionTable; EXECUTE 'CREATE TABLE DecisionTable (' || @BitColumns || ')'; EXECUTE 'WITH Product AS (SELECT ' || @Columns || ' FROM (SELECT * FROM ' || @TableName || ' WHERE ' || @FirstName || ' = ''' || @FirstValue || ''') AS D, ' || ' (SELECT * FROM ' || @TableName || ' WHERE ' || @FirstName || '!= ''' || @FirstValue || ''') AS E) ' || 'INSERT INTO DecisionTable ' || 'SELECT DISTINCT ' || @Derivats || ' FROM Product AS T, (SELECT * FROM Product LIMIT 1) AS V' || ' WHERE 1 = (SELECT COUNT(*) FROM Product AS R WHERE ' || @Duplicates || ')'; --Sort columns by checking their values: all zeros means that --the column belongs to the same component as @FirstName; --otherwise the column belongs to the co-component. DECLARE BitColumns TEXT; ColumnName TEXT; FirstCompAttrs TEXT; SecondCompAttrs TEXT; Query TEXT; ColumnCursor CURSOR FOR SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @TableName AND COLUMN_NAME <> @FirstName; BEGIN --CREATE BIT COLUMNS FOR THE TEMPORARY TABLE SELECT STRING_AGG( COLUMN_NAME || ' BIT', ',' ) INTO BitColumns FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @TableName AND COLUMN_NAME <> @FirstName; --CREATE TEMPORARY TABLE FOR BIT VECTORS Query := 'CREATE TEMPORARY TABLE DecisionTable (' || BitColumns || ');'; EXECUTE Query; --INSERT BIT VECTORS INTO THE TEMPORARY TABLE Query := 'WITH Product AS (SELECT ' || @Columns || ' FROM (SELECT * FROM ' || @TableName || ' WHERE ' || @FirstName || ' = ''' || @FirstValue || ''') AS D, ' || ' (SELECT * FROM ' || @TableName || ' WHERE ' || @FirstName || '!= ''' || @FirstValue || ''') AS E) ' || 'INSERT INTO DecisionTable ' || 'SELECT DISTINCT ' || @Derivats || ' FROM Product AS T, (SELECT * FROM Product LIMIT 1) AS V' || ' WHERE 1 = (SELECT COUNT(*) FROM Product AS R WHERE ' || @Duplicates || ');'; EXECUTE Query; --SORT COLUMNS BY CHECKING THEIR VALUES OPEN ColumnCursor; FETCH NEXT FROM ColumnCursor INTO ColumnName; WHILE (FOUND) LOOP Query := 'SELECT 1 FROM DecisionTable WHERE ' || ColumnName || ' = 1;'; EXECUTE Query; IF (FOUND) THEN RAISE NOTICE 'First component %', ColumnName; ELSE RAISE NOTICE 'Second component %', ColumnName; END IF; FETCH NEXT FROM ColumnCursor INTO ColumnName; END LOOP; CLOSE ColumnCursor; --CREATE RESULTING TABLES BEING COMPONENTS OF CARTESIAN DECOMPOSITION --FirstCompAttrs and SecondCompAttrs must be initialized by the component's attributes --Query := 'CREATE TABLE FirstComponent' || -- ' AS (SELECT DISTINCT ' || FirstCompAttrs || -- ' FROM ' || @TableName || '); ' || -- 'CREATE TABLE SecondComponent' || -- ' AS (SELECT DISTINCT ' || SecondCompAttrs || -- ' FROM ' || @TableName || '); '; --EXECUTE Query; END; -- Create a temporary table for storing the Decision Table DROP TABLE IF EXISTS DecisionTable; CREATE TEMP TABLE DecisionTable AS WITH Product AS ( SELECT * FROM ( SELECT * FROM @TableName WHERE @FirstName = @FirstValue ) AS D CROSS JOIN ( SELECT * FROM @TableName WHERE @FirstName != @FirstValue ) AS E ) SELECT DISTINCT ON (@Derivats) @Derivats FROM ( SELECT *, ROW_NUMBER() OVER (PARTITION BY @Derivats ORDER BY @BitColumns) AS row_num FROM ( SELECT *, CASE WHEN @BitColumns = '' THEN 0 ELSE CAST(LEFT(@BitColumns, CHARINDEX(',', @BitColumns + ',') - 1) AS INTEGER) END AS BitValue FROM Product ) AS T ) AS T2 WHERE row_num = 1; -- Sort columns by checking their values: all zeros means that -- the column belongs to the same component as @FirstName; -- otherwise the column belongs to the co-component. DO $$ DECLARE column_name VARCHAR; column_cursor CURSOR FOR SELECT column_name FROM information_schema.columns WHERE table_name = @TableName AND column_name != @FirstName; BEGIN OPEN column_cursor; LOOP FETCH column_cursor INTO column_name; EXIT WHEN NOT FOUND; IF EXISTS ( SELECT 1 FROM DecisionTable WHERE column_name = 1 ) THEN RAISE NOTICE 'First component %', column_name; ELSE RAISE NOTICE 'Second component %', column_name; END IF; END LOOP; CLOSE column_cursor; END $$; -- Drop the Decision Table DROP TABLE DecisionTable;
Stuck with a problem? Got Error? Ask ChatGPT!
Copy Clear