Migrate values of one database table into another table with different columns - mysql

I'm new to SQL, so I think this will have a simple answer, but I'm having trouble tracking down a comparable example via google.
I have two tables in a SQL database with similar values, but a different number of columns with different column names. I need to migrate the the values from the first database (catalog_product_entity_tier_price) into the second database (mb_tierprices_list) and then fill in the gaps with a default value.
This is where I'm up to:
INSERT INTO catalog_product_entity_tier_price (entity_id, website_id, qty, value)
SELECT entity_id, website_id, price_qty, percent
FROM mb_tierprices_list;
But I also need to handle three more columns in catalog_product_entity_tier_price with default values:
value_id (this is set to AUTO_INCREMENT, so nothing to do there)
all_groups = 1
customer_group_id = 0
Should I split this into two queries and just do a second one like so:
INSERT INTO catalog_product_entity_tier_price (all_groups, customer_group_id)
VALUES (1, 0);
Is there a preferred way to accomplish this?

Just put the default values in your select like this:
INSERT INTO catalog_product_entity_tier_price (entity_id, website_id, qty, value, all_groups, customer_group_id)
SELECT entity_id, website_id, price_qty, percent, 1, 0
FROM mb_tierprices_list;

Related

Insert only two columns data from another table and leave the rest with default values

MySql table has four columns. How to insert two column data from another table and leave the other two columns to be filled out manually.
insert into faulthistory (D_ID,D_IP,D_Status,Date_time)
select IP_ID,D_IP from device where D_IP='192.168.1.1', '0',now();
Put the "manual" values in the select list:
insert into faulthistory
(D_ID,D_IP,D_Status,Date_time)
select IP_ID, D_IP, '0', now() from device where D_IP='192.168.1.1'
You could alternatively define default values for these two columns.

filtering from sql

I use my SQL for my app.
Say I have a table of all registered users for my app.
say I have users at hand and I want to filter (or select) from my database the only ones that are registered.
For example my data base have user1,user2......user100
and input user set : user3,user5,user10,user999,user2000 so the output of the query will be : user3,user5 and user 10 only.
Thank you in advance
You seem to want in:
select t.*
from t
where user_id in ('user3', 'user5', 'user10', 'user999', 'user2000')
This will return only the matching users.
The format the user is passing these values is very important here. I am assuming that you have different rows of information. If in that case, you could make use of the below code.
Declare #MyTableVar table
(User_ID VARCHAR(32) primary key)
INSERT #MyTableVar VALUES ('user3')
INSERT #MyTableVar VALUES ('user5')
INSERT #MyTableVar VALUES ('user10')
INSERT #MyTableVar VALUES ('user999')
INSERT #MyTableVar VALUES ('user2000')
SELECT *
FROM #MyTableVar
WHERE User_ID NOT IN (SELECT USER_ID FROM database.schema.table_name)
If your user is passing values in the same row you can convert them to multiple rows using CROSS APPLY. Example can be seen here
Kartheek

Merge parts of two different strings into new string

I have three columns PRODUCTID, PRODUCTNAME, PRODUCTCODE within a table.
I wish to insert a new product creating the PRODUCTID from the other columns
How do I take the first two letters of PRODUCTNAME and the last four numbers of PRODUCTCODE and populate them into PRODUCTID?
I do not want a product to be duplicated within the table and if attempted I want the table to remain unchanged. The default PRODUCTID is DEFAULT.
I have so far got:
INSERT INTO `v1_products` (`PRODUCTNAME`, `PRODUCTNUMBER`) VALUES ("EXAMPLE", "EXAMPLE4444");
UPDATE `v1_products`
SET `PRODUCTID`=(SELECT CONCAT(
(SELECT LEFT(`PRODUCTNAME`,2)) , (SELECT RIGHT(`PRODUCTNUMBER`,4))))
WHERE `PRODUCTID`= "DEFALT" AND `PRODUCTID`!=`PRODUCTID`
LIMIT 1
First off I would reccomend setting the PRODUCTID column to be unique. This will prevent any products from having the same values. If your default PRODUCTID is "default" then you may need to do this after updating the ids.
Your UPDATE statement is fine except from the WHERE clause:
WHERE `PRODUCTID`= "DEFALT" AND `PRODUCTID`!=`PRODUCTID`
There's a typo in "DEFAULT" and
`PRODUCTID`!=`PRODUCTID`
Will never be true.
WHERE `PRODUCTID`= "DEFAULT"
Should be enough.
The above will fix existing products with incorrect ids. Now you should change your insert so that PRODUCTID is set correctly for each new product. You can do this by simply adding the CONCAT you used in the update statement:
INSERT INTO `v1_products` (`PRODUCTID`, `PRODUCTNAME`, `PRODUCTNUMBER`)
VALUES (
CONCAT(
LEFT("EXAMPLE",2),
RIGHT("EXAMPLE4444",4)),
"EXAMPLE",
"EXAMPLE4444");
From the discussion in the comments an example of only setting the columns values once:
INSERT INTO v1_products (PRODUCTNAME, PRODUCTNUMBER,PRODUCTID)
VALUES (
"EXAMPLE",
"EXAMPLE4444",
CONCAT( LEFT(PRODUCTNAME,2), RIGHT(PRODUCTNUMBER,4)));

INSERT INTO with SubQuery MySQL

I have this Statement:
INSERT INTO qa_costpriceslog (item_code, invoice_code, item_costprice)
VALUES (1, 2, (SELECT item_costprice FROM qa_items WHERE item_code = 1));
I'm trying to insert a value copy the same data of item_costprice, but show me the error:
Error Code: 1136. Column count doesn't match value count at row 1
How i can solve this?
Use numeric literals with aliases inside a SELECT statement. No () are necessary around the SELECT component.
INSERT INTO qa_costpriceslog (item_code, invoice_code, item_costprice)
SELECT
/* Literal number values with column aliases */
1 AS item_code,
2 AS invoice_code,
item_costprice
FROM qa_items
WHERE item_code = 1;
Note that in context of an INSERT INTO...SELECT, the aliases are not actually necessary and you can just SELECT 1, 2, item_costprice, but in a normal SELECT you'll need the aliases to access the columns returned.
You can just simply e.g.
INSERT INTO modulesToSections (fk_moduleId, fk_sectionId, `order`) VALUES
((SELECT id FROM modules WHERE title="Top bar"),0,-100);
I was disappointed at the "all or nothing" answers. I needed (again) to INSERT some data and SELECT an id from an existing table.
INSERT INTO table1 (id_table2, name) VALUES ((SELECT id FROM table2 LIMIT 1), 'Example');
The sub-select on an INSERT query should use parenthesis in addition to the comma as deliminators.
For those having trouble with using a SELECT within an INSERT I recommend testing your SELECT independently first and ensuring that the correct number of columns match for both queries.
Your insert statement contains too many columns on the left-hand side or not enough columns on the right hand side. The part before the VALUES has 7 columns listed, but the second part after VALUES only has 3 columns returned: 1, 2, then the sub-query only returns 1 column.
EDIT: Well, it did before someone modified the query....
As a sidenote to the good answer of Michael Berkowski:
You can also dynamically add fields (or have them prepared if you're working with php skripts) like so:
INSERT INTO table_a(col1, col2, col3)
SELECT
col1,
col2,
CURRENT_TIMESTAMP()
FROM table_B
WHERE b.col1 = a.col1;
If you need to transfer without adding new data, you can use NULL as a placeholder.
If you have multiple string values you want to add, you can put them into a temporary table and then cross join it with the value you want.
-- Create temp table
CREATE TEMPORARY TABLE NewStrings (
NewString VARCHAR(50)
);
-- Populate temp table
INSERT INTO NewStrings (NewString) VALUES ('Hello'), ('World'), ('Hi');
-- Insert desired rows into permanent table
INSERT INTO PermanentTable (OtherID, NewString)
WITH OtherSelect AS (
SELECT OtherID AS OtherID FROM OtherTable WHERE OtherName = 'Other Name'
)
SELECT os.OtherID, ns.NewString
FROM OtherSelect os, NewStrings ns;
This way, you only have to define the strings in one place, and you only have to do the query in one place. If you used subqueries like I initially did and like Elendurwen and John suggest, you have to type the subquery into every row. But using temporary tables and a CTE in this way, you can write the query only once.

Is this a Efficient way to query relational tables on MySQL?

I'm dealing with a relational table and I've been wondering if there's a way to lower the number of queries I need to make when inserting data to the tables..
Here are the queries I currently use:
I insert the "main" values.
INSERT INTO products
(title, description, status, url)
VALUES
('some title', 'description of doom', 1, 'some-title');
We make it insert the value only if it doesn't exist already.
INSERT IGNORE INTO values
(value)
VALUES
('example value');
Since I'm not sure if the query was actually inserted, I get the id..
SELECT id
FROM
values
WHERE
value = 'example value';
Where "?" is the ID I got from the last query.
INSERT INTO link
( id_product, id_catalog, id_value )
VALUES
( 33, 1, ? );
This means that each extra value I need to add will cost 3 queries. So my question is: Is there a more efficient way to do this?
You can do this to at least drop one of the queries:
INSERT INTO link
( id_product, id_catalog, id_value )
VALUES
( 33, 1, (SELECT id
FROM values
WHERE value = 'example value') );
I basically am replacing the '?' with a sub select of the second query to get the id.
"Is there a more efficient way to do this?"
No. Not really. Creating three things takes three inserts.
You should be able to tell whether the insert succeeded with the ROW___COUNT() function from inside MySQL. If calling from another language (e.g. PHP), the mysql_query or equivalent function will return the row count.
You could use an INSERT INTO ... ON DUPLICATE KEY UPDATE statement.
This does, however, require that the primary key be one of the values for the insert, so it doesn't work on tables with an auto-increment.