I am trying to update some fields, without mentioning the field name in the query, with values from other tables.
EXISTING_TABLE:
+--------------------+
| Dynamic Columns |
+---+------+------+------+------+
|ID |Item |ABC |GHQ |XYZ |
+---+------+------+------+------+
|1 |Item1 |100 |200 |Null |
|2 |Item2 |Null |Null |600 |
+---+------+------+------+------+
With the query I am trying to formulate, the result of the table should be:
RESULT_TABLE:
+-----------------+
| Dynamic Columns |
+---+------+-----+-----+-----+
|ID |Item |ABC |GHQ |XYZ |
+---+------+-----+-----+-----+
|1 |Item1 |100 |200 |300 |
|2 |Item2 |400 |500 |600 |
+---+------+-----+-----+-----+
Those nulls should be replaced by the value of the source table below. In this table your will find how the fields above are dynamically produced.
SOURCE_TABLE:
+------+----------+------------+---------+
|ID |Vendor |Item |Price |
+------+----------+------------+---------+
|1 |ABC |Item1 |100 |
|2 |ABC |Item2 |400 |
|3 |GHQ |Item1 |200 |
|4 |GHQ |Item2 |500 |
|5 |XYZ |Item1 |300 |
|6 |XYZ |Item2 |600 |
+------+----------+------------+---------+
The tricky part here of this query is the columns are random or dynamic. It can only be determined at runtime. So, I should be using some syntax here to identify first the columns and update with values.
I am trying in this code but I could not find the expression for the for column_with_null_value and current_row_item:
CREATE DEFINER=`admin`@`%` PROCEDURE `null_update`()
BEGIN
DECLARE n INT DEFAULT 0;
DECLARE i INT DEFAULT 0;
SELECT COUNT(*) FROM canvass_prices INTO n;
SET i = 0;
WHILE i < n DO
UPDATE existing_table SET column_with_null_value = (SELECT price
FROM source_table WHERE vendor = column_with_null_value
AND item = current_row_item)
WHERE item = current_row_item;
SET i = i + 1;
END WHILE;
END;
UPDATE 1 Edited the entire question for clearer illustration of my case including the source table and my stored procedure attempt.
UPDATE 2 You may wonder why the data was not captured initially by the existing_table from source_table, it is because there were procedures needed to run to capture minimum prices in each item queried that leaves some columns remained null in the next item query.
UPDATE 3 Here's my actual script on how I arrived with the tables above.
This is the initial query for the first item:
DROP VIEW IF EXISTS min_prices;
CREATE VIEW min_prices AS
SELECT item_var.list_id, vendor.vendor_name, price
FROM price
JOIN item_var ON price.item_var_id = item_var.list_id
JOIN vendor ON price.vendor_id = vendor.list_id
JOIN item ON item_var.item_id = item.list_id
WHERE item_var.list_id = 1
ORDER BY price ASC
LIMIT 3;
SET @vendor1_name = (SELECT vendor_name FROM min_prices LIMIT 0, 1);
SET @vendor2_name = (SELECT vendor_name FROM min_prices LIMIT 1, 1);
SET @vendor3_name = (SELECT vendor_name FROM min_prices LIMIT 2, 1);
DROP TABLE IF EXISTS canvass_prices;
SET @canvass_var = CONCAT("CREATE TABLE canvass_prices AS
SELECT item.name, item_var.container, item_var.size,
(SELECT price FROM min_prices LIMIT 0, 1) AS '", @vendor1_name, "' ,
(SELECT price FROM min_prices LIMIT 1, 1) AS '", @vendor2_name, "' ,
(SELECT price FROM min_prices LIMIT 2, 1) AS '", @vendor3_name, "'
FROM item_var
JOIN item ON item_var.item_id = item.list_id
WHERE item_var.list_id = (SELECT DISTINCT list_id FROM min_prices)");
PREPARE canvass_statement FROM @canvass_var;
EXECUTE canvass_statement;
DEALLOCATE PREPARE canvass_statement;
SELECT * FROM canvass_prices;
And this is the second query for the succeeding items:
DROP VIEW IF EXISTS min_prices;
CREATE VIEW min_prices AS
SELECT item.name, item_var.container, item_var.size, vendor.vendor_name, price
FROM price
JOIN item_var ON price.item_var_id = item_var.list_id
JOIN vendor ON price.vendor_id = vendor.list_id
JOIN item ON item_var.item_id = item.list_id
WHERE item_var.list_id = 9
ORDER BY price ASC
LIMIT 3;
SET @vendor1_name = (SELECT vendor_name FROM min_prices LIMIT 0, 1);
SET @vendor2_name = (SELECT vendor_name FROM min_prices LIMIT 1, 1);
SET @vendor3_name = (SELECT vendor_name FROM min_prices LIMIT 2, 1);
call project_x.vendor1_name();
call project_x.vendor2_name();
call project_x.vendor3_name();
SET @canvass_var = CONCAT("INSERT INTO canvass_prices (name, container, size,
`", @vendor1_name, "`,
`", @vendor2_name, "`,
`", @vendor3_name, "`)
VALUES ((SELECT DISTINCT name FROM min_prices),
(SELECT DISTINCT container FROM min_prices),
(SELECT DISTINCT size FROM min_prices),
(SELECT price FROM min_prices LIMIT 0, 1),
(SELECT price FROM min_prices LIMIT 1, 1),
(SELECT price FROM min_prices LIMIT 2, 1))");
PREPARE canvass_statement FROM @canvass_var;
EXECUTE canvass_statement;
DEALLOCATE PREPARE canvass_statement;
SELECT DISTINCT * FROM canvass_prices;