INNER JOIN 3 tables with reference INFILE - mysql

I have a csv with two columns, col1 is a barcode, col2 is stock quantity.
I have the 3 tables.
Table1:product_option_value
Fields: product_option_value_id, product_option_id, product_id, option_id, option_value_id, quantity, subtract, price, price_prefix, points, points_prefix, weight, weight_prefix
Table2: product_option_newvalue
Fields: product_id, product_option_value_id, sku, upc
I am trying to update the QUANTITY field of the table product_option_value using the sku and quantity in my CSV file, the part I’m having trouble with is I have to use product_option_value_id in the product_option_newvalue table to update QUANTITY field in product_option_value, how would I reference between the two?
Here is what I have. It does not work.
CREATE TABLE oc_product_import LIKE oc_product_option_value;
LOAD DATA INFILE '/var/lib/mysql-files/out.csv'
INTO TABLE oc_product_import
FIELDS TERMINATED BY ','
OPTIONALLY ENCLOSED BY '"'
(sku, quantity);
UPDATE oc_product_option_value AS R
INNER JOIN oc_product_import AS P
ON R.product_option_value_id = P.product_option_value_id
SET R.quantity = P.sku;
DROP TABLE product_import;"
Edit: my issue seems to be that the barcode is only stored in product_option_newvalue, and can only be linked to quantity by referencing product_option_value_id, in both tables, To update the quantity in the product_option_value table.
EDIT2: This is similar code that is working for me. But it does not have to reference PRODUCT_OPTION_VALUE_ID issue I’m working with in the two table as the barcode is included in the product table and not an additional table by reference
DROP TABLE IF EXISTS oc_product_import;
CREATE TABLE oc_product_import LIKE oc_product
LOAD DATA INFILE '/var/lib/mysql-files/out.csv'
INTO TABLE oc_product_import
FIELDS TERMINATED BY ','
OPTIONALLY ENCLOSED BY ';'
(sku, quantity);
UPDATE oc_product AS R
INNER JOIN oc_product_import AS P
ON R.sku = P.sku
SET R.quantity = P.quantity;
DROP TABLE oc_product_import;"

I would recommend using MySQL Workbench. It isn't the best, but it definitely makes situations like these easier to manage.
After you get it setup you can right click on a table and select table data import wizard and manually add a csv file that way.
If you get any errors with this let me know.
Also, if you are on mac you can simply brew cask install mysqlworkbench in terminal.

Related

LOAD DATA LOCAL INFILE is producing null where with inner join update

I`m trying to upload a file in my opencart database, I want to bulk upload the product UPC numbers and I'm using this query:
CREATE TEMPORARY TABLE `my_temp_table`
(
product_id INT(11),
name VARCHAR(255),
upc VARCHAR(12)
);
LOAD DATA LOCAL INFILE '/home/mupckuco/dev/oc_product.csv'
INTO TABLE `my_temp_table`
FIELDS TERMINATED BY ','
(`product_id`, `name`, `upc`);
UPDATE `oc_product`
INNER JOIN `my_temp_table` on `my_temp_table`.`product_id` = `oc_product`.`product_id`
SET `oc_product`.`upc` = `my_temp_table`.`upc`;
DROP TEMPORARY TABLE `my_temp_table`;
Firstly I have exported the table with product id, product name and the column with the product UPC with the following query:
SELECT `oc_product`.`product_id` , `oc_product_description`.`name` , `oc_product`.`upc`
FROM `oc_product`
INNER JOIN `oc_product_description` ON `oc_product`.`product_id` = `oc_product_description`.`product_id`
BUT unfortunately, this line
UPDATE `oc_product` INNER JOIN `my_temp_table` on `my_temp_table`.`product_id` = `oc_product`.`product_id` SET `oc_product`.`upc` = `my_temp_table`.`upc`
is inserting NULLs in the table.
I have tried firstly to create a normal table (not temporary) so there i saw that everything in the UPC column is inserted as NULL.
I'm doing export as CSV for Microsoft Excel and I'm saving the file with the same extension. Where can be the problem?
This are some examples from the csv file and the my_temp_table results after updating:
Wow, I have never seem someone try to import a CSV directly in to the database and then run an update with a JOIN, perhaps your background is as a DBA rather than a PHP developer?
Anyway, I suggest you import the CSV in to an array in PHP:
$csv = array_map('str_getcsv', file('/home/mupckuco/dev/oc_product.csv'));
And then loop over it to generate the UPDATE statement.

Import CSV to Update rows in table

There are approximately 26K products (posts) and each product has meta values like this:
The post_id column is the product id in db and the _sku (meta_key) is the unique id for each product.
I've received a new CSV file that updates all of the values (meta_value) for _sale_price (meta_key) of each product. The CSV file looks like:
SKU, Sale Price
How do I import this CSV to update only the _sale_price row based on the post_id (product id) & _sku value?
Output Example:
I know how to do this in PHP by looping through the CSV and selecting & executing an update for each single product but this seems inefficient.
Preferably with phpMyAdmin and by using LOAD DATA INFILE.
You can use temporary table to hold the update data and then run single update statement.
CREATE TEMPORARY TABLE temp_update_table (meta_key, meta_value)
LOAD DATA INFILE 'your_csv_pathname'
INTO TABLE temp_update_table FIELDS TERMINATED BY ';' (meta_key, meta_value);
UPDATE "table"
INNER JOIN temp_update_table on temp_update_table.meta_key = "table".meta_key
SET "table".meta_value = temp_update_table.meta_value;
DROP TEMPORARY TABLE temp_update_table;
If product_id is the unique column of that table, you can do that using CSV:
Have a CSV file of those you want to import with their unique ID. CSV file must be in same order of the table column, put all your columns and no column name
Then in phpMyAdmin, go to the table of database, click import
Select CSV in the drop-down of Format field
Make sure "Update data when duplicate keys found on import (add ON DUPLICATE KEY UPDATE)" is checked.
You can import the new data into another table (table2). Then update your primary table (table1) using a update with a sub-select:
UPDATE table1 t1 set
sale_price = (select meta_value from table2 t2 where t2.post_id = t1.product_id)
WHERE
(select count(*) from table2 t2 where t1.product_id = t2.post_id) > 0
This is obviously a simplification and you will most likely need to constrain your query a little further.
Make sure to backup your full database before attempting. I recommend you work on a non-production database until the process works flawlessly.
It seems to me that rAndom69's answer does not work on postgresql 12 but the join with the WHERE work:
UPDATE tableA
SET fieldToPopulateInTableA = temp_update_table.fieldPopulated
FROM temp_update_table
WHERE tableA.correspondingField = temp_update_table.correspondingField

Uploading CSV into MySQL table with simultaneous JOIN

What I'm trying to do is upload a CSV into a table, while appending information from a third table to the target table using JOIN.
The CSV import.csv (with 1M rows) looks like this:
firstname | lastname
The target table "names" looks like this:
firstname | lastname | gender
And the table "gender" (with 700k rows) looks like this:
firstname | gender
So, my ideal query would look something like this:
LOAD DATA LOCAL INFILE "import.csv"
INTO TABLE names n
LEFT JOIN gender g ON(g.firstname=n.firstname)
Something along those lines, to combine the import with the join so the end result in names has the data from gender and the CSV.
However, I know that LOAD DATA LOCAL INFILE can't be combined with JOIN, and attempts to use INSERT plus JOIN for each line are too CPU intensive.
Any ideas?
You can use SET clause of LOAD DATA INFILE to achieve your goal
LOAD DATA LOCAL INFILE '/path/to/your/file.csv'
INTO TABLE names
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n' -- or '\r\n' if file has been prepared in Windows
IGNORE 1 LINES -- use this if your first line contains column headers
(#first, #last)
SET firstname = #first,
lastname = #last,
gender =
(
SELECT gender
FROM gender
WHERE firstname = #first
LIMIT 1
)
Make sure that:
you have an index on firstname column in gender table
you don't have any indices on names table before you load data. Add them (indices) after you complete the load.
MySql LOAD DATA INFILE syntax doesn't define JOIN.
CREATA TABLE temporary_table...
LOAD DATA INFILE "import.csv" INTO TABLE temporary_table FIELDS TERMINATED BY '|' ENCLOSED BY '"' LINES TERMINATED BY '\n';
INSERT INTO names(t.firstname, t.lastname, g.gender) SELECT FROM temporary_table t LEFT JOIN gender g ON(g.firstname=n.firstname);
In my experience, the best way to load data into a database is to place it in a staging table first where all the columns are characters. Then, transform the data in the database to your final output.
Applying this to your code:
LOAD DATA LOCAL INFILE "import.csv"
INTO TABLE names_staging;
CREATE TABLE names as
select n.firstname, n.lastname, g.gender
from names_staging n LEFT JOIN
gender g
ON g.firstname = n.firstname;
This makes it possible to identify and fix problems from the data load. You can also easily add additional columns such as primary keys and insert dates into the final table.

mysql insert update LOAD DATA LOCAL INFILE

i am using LOAD DATA LOCAL INFILE to load data into temp table mid.then i use a update query to update found in table product.The only matching field in both is the model.
$q = "LOAD DATA LOCAL INFILE 'Mid.csv' INTO TABLE mid
FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\n' IGNORE 1 LINES
(#col1,#col2,#col3,#col4,#col5,#col6) set model=#col1,price=#col3,stock=#col6 ";
mysql_query($q, $db);
mysql_query('UPDATE mid m, products p set p.products_price= m.price,p.products_quantity= m.stock where p.products_model= m.model');
It works and update the product table.the issue i am having is that there new records in mid table which don't get inserted as i am using the update statement.
I have looked at the insert query and update on duplicate.I have seen loads of examples of when it has to work on one table but none where i have to match it against another table.
Either i am searching for the wrong thing or there is another way to to do this.
i would appreciate any help.
regards
naf
I'm not sure what the other columns in the product table are, but here's a basic approach that should work for you based on the 3 columns in your example, assuming the products_model column is unique in the products table:
insert into products (products_price,products_quantity,products_model)
select price, stock, model
from mid
on duplicate key update
products_price = values(products_price),
products_quantity = values(products_quantity)

Import CSV to Update only one column in table

I have a table that looks like this:
products
--------
id, product, sku, department, quantity
There are approximately 800,000 entries in this table. I have received a new CSV file that updates all of the quantities of each product, for example:
productA, 12
productB, 71
productC, 92
So there are approximately 750,000 updates (50,000 products had no change in quantity).
My question is, how do I import this CSV to update only the quantity based off of the product (unique) but leave the sku, department, and other fields alone? I know how to do this in PHP by looping through the CSV and executing an update for each single line but this seems inefficient.
You can use LOAD DATA INFILE to bulk load the 800,000 rows of data into a temporary table, then use multiple-table UPDATE syntax to join your existing table to the temporary table and update the quantity values.
For example:
CREATE TEMPORARY TABLE your_temp_table LIKE your_table;
LOAD DATA INFILE '/tmp/your_file.csv'
INTO TABLE your_temp_table
FIELDS TERMINATED BY ','
(id, product, sku, department, quantity);
UPDATE your_table
INNER JOIN your_temp_table on your_temp_table.id = your_table.id
SET your_table.quantity = your_temp_table.quantity;
DROP TEMPORARY TABLE your_temp_table;
I would load the update data into a seperate table UPDATE_TABLE and perform an update within MySQL using:
UPDATE PRODUCTS P SET P.QUANTITY=(
SELECT UPDATE_QUANTITY
FROM UPDATE_TABLE
WHERE UPDATE_PRODUCT=P.PRODUCT
)
I dont have a MySQL at hand right now, so I can check the syntax perfectly, it might be you need to add a LIMIT 0,1 to the inner SELECT.
Answer from #ike-walker is indeed correct but also remember to double check how your CSV data if formatted. Many times for example CSV files can have string fields enclosed in double quotes ", and lines ending with \r\n if working on Windows.
By default is assumed that no enclosing character is used and line ending is \n.
More info and examples here https://mariadb.com/kb/en/importing-data-into-mariadb/
This can be fixed by using additional options for FIELDS and LINES
CREATE TEMPORARY TABLE your_temp_table LIKE your_table;
LOAD DATA INFILE '/tmp/your_file.csv'
INTO TABLE your_temp_table
FIELDS
TERMINATED BY ','
OPTIONALLY ENCLOSED BY '"' -- new option
LINES TERMINATED BY '\r\n' -- new option
(id, product, sku, department, quantity);
UPDATE your_table
INNER JOIN your_temp_table on your_temp_table.id = your_table.id
SET your_table.quantity = your_temp_table.quantity;
DROP TEMPORARY TABLE your_temp_table;