MySQL INSERT INTO table 1 SELECT table 2 with different column name - mysql

I have a table (pdt_1) in database (db_1) and another table (pdt_2) in another database (db_2).
I met pdt_1 and pdt_2 to find pdt_1 products not present and published in pdt_2.
functional code :
SELECT * FROM db_1.pdt_1 AS lm
WHERE lm.product_sku
NOT IN (SELECT DISTINCT product_cip7 FROM db_2.pdt_2)
AND lm.product_publish=‘Y'
finally, I need to insert the result of this query in pdt_2.
However, the structure of pdt_1 and pdt_2 are different.
Example:
- columns's names
- columns's numbers
I also need an auto_increment id for pdt_1 products inserted into pdt_2.
I need help.
NB : sorry for my poor english :(

If you want a new table with just the id and product_sku, try:
INSERT INTO new_table # with id and product_sku from first table
SELECT pdt_1.id,
pdt_1.product_sku
FROM db_1.pdt_1
LEFT JOIN db_2.pdt_2
ON pdt_1.product_sku = pdt_2.product_cip7
WHERE pdt_2.product_cip7 IS NULL
AND pdt_1.product_publish = 'Y'

Related

MYSQL Update Table set column equal to select column from same table

I have a new column in my database and I need fill it up with the value of the same column from one specific row. I want to create a feature "copy to all"
For example add the same price to all the products taken from the first row:
ID NAME PRICE
1 PROD1 5
2 PROD2 0
3 PROD3 0
4 PROD4 0
I am trying to select the PRICE of the first row (ID 1) and copy it to all the other rows.
I have tried:
UPDATE PRODUCTS SET PRICE = (select PRICE from PRODUCTS where ID = 1);
I want to end up with this
ID NAME PRICE
1 PROD1 5
2 PROD2 5
3 PROD3 5
4 PROD4 5
But I get this error:
Table 'PRODUCTS' is specified twice,
both as a target for 'UPDATE' and as a separate source for data
I tried specifying each table separately
UPDATE PRODUCTS as a SET a.PRICE = (select b.PRICE from PRODUCTS as b where b.ID = 1);
But I get the same error.
Table 'a' is specified twice,
both as a target for 'UPDATE' and as a separate source for data
Maybe I have to create a temporary table and copy from it?
Any hints on how to accomplish this?
Thanks.
You can do it by nesting the select query:
UPDATE PRODUCTS
SET PRICE = (
select PRICE from (select PRICE from PRODUCTS where ID = 1) t
);
See the demo.
Another way to do it, with a self CROSS JOIN:
UPDATE PRODUCTS p CROSS JOIN (
select PRICE from PRODUCTS where ID = 1
) t
SET p.PRICE = t.PRICE;
See the demo.
This wouldn't work logically, as SQL would try to fetch the data it is updating.
Try running your nested statement select PRICE from PRODUCTS where ID = 1 seperately, saving the response and then running your main statement: "UPDATE PRODUCTS SET PRICE = " + newPrice
If this is a SQL script, i suggest you to break it into 2 queries using a variable:
select #var := PRICE from PRODUCTS where ID = 1;
UPDATE PRODUCTS SET PRICE = #var;
Variables are much more easier than temporary table in my opinion.
I've not fully tested, but the syntax should be that
After looking at many answers on other posts and websites, (none of them had the precise answer), I found the solution with this query, and yes we need temp tables:
CREATE TEMPORARY TABLE tmptable SELECT ID, PRICE FROM PRODUCTS WHERE ID = 1;
UPDATE PRODUCTS SET `PRICE` = (select tmptable.`PRICE` from tmptable where tmptable.ID = 1);
BUT! #forpas solution's is really good and works without creating a temp table.
enjoy.
NEW question: is the temp table removed automatically? Leave me a comment.
Cheers

mySQL SELECT values from a TABLE where the TABLE name is based on a field value

Here's are very simplified versions of my tables.
[stock_adjust]
id
batch_table_name
batch_id
adjustment_reason
qty
[ingredient_batch]
id
batch_name
...lots of other columns
[product_batch]
id
batch_name
...lots of other columns
[packaging_batch
id
batch_name
...lots of other columns
stock_adjust contains the name of the correct batch table in the column batch_table_name which will either be "ingredient_batch", "product_batch" or "packaging_batch". I need to get the values from the correct batch table for each entry. The pseudo code for this would look something like the following:
SELECT sa.id, sa.adjustment_reason, sa.qty, batch.batch_name
FROM stock_adjust AS sa, [sa.batch_table_name] AS batch
WHERE sa.batch_id=batch.id
I have tried to simplify the description and tables as much as possible, hopefully I haven't simplified it too much and the above makes sense?
I have found several questions regarding similar issues to the following, but they either do not work correctly in this situation or I am not understanding the question correctly.
While I would recommend updating your database schema, here's an approach that could work for you given your scenario:
select sa.id, b.batch_name
from stock_adjust sa join (
select id, batch_name, 'ingredient_batch' table_name from ingredient_batch
union all
select id, batch_name, 'product_branch' table_name from product_branch
union all
select id, batch_name, 'packaging_batch' table_name from packaging_batch
) b on sa.batch_table_id = b.id and b.table_name = sa.batch_table_name
SQL Fiddle Demo
Maybee a dynamic query could be the solution. Check this answer SELECT * FROM #variable

Some doubts about this simple INNER JOIN query?

I have the following doubt about this simple INNER JOIN query.
I have these two tables that have to be joined togheter:
The first table is named VulnerabilityFix and contains the following columns:
Id: int identity
FixName: varchar
Vendor: varchar
Title: varchar
Version: varchar
The second table is named VulnerabilityAlertDocument_VulnerabilityFix (this bind the previous table to another table, but this is not important at this time) and contains the following columns:
VulnerabilityAlertDocumentId: int
VulnerabilityFixId: int
Now, on my DB the VulnerabilityFix table contains only an empty record (this record have an id but all the other fields are empty\null), infact if I perform a select *, I obtain:
select * from VulnerabilityFix
Id FixName Vendor Title Version
1
Into the VulnerabilityAlertDocument_VulnerabilityFix I have something like this:
select * from VulnerabilityAlertDocument_VulnerabilityFix
VulnerabilityAlertDocumentId VulnerabilityFixId
78385 1
78386 1
....................................................
....................................................
....................................................
78398 1
Ok, so I want JOIN toghert these 2 table in in such a way that passing the value of the VulnerabilityAlertDocumentId field of the VulnerabilityAlertDocument_VulnerabilityFix table, I obtain all the related record in the VulnerabilityFix table.
So in this case I aspect to retrieve the previous only record that having an id (having a value equal to 1) and all the other fields are empty\null.
So my query is:
SELECT VF.* FROM VulnerabilityAlertDocument_VulnerabilityFix VAD_VF
INNER JOIN VulnerabilityFix VF ON VAD_VF.VulnerabilityAlertDocumentId = VF.Id
WHERE VAD_VF.VulnerabilityAlertDocumentId = 1
The problem is that when I execute this query I obtain an empty set of records and not the unique record that I expetc to obtain.
Why? What am I missing?
Tnx
I think your query should be more like:
SELECT VF.* FROM VulnerabilityAlertDocument_VulnerabilityFix VAD_VF
INNER JOIN VulnerabilityFix VF ON VAD_VF.VulnerabilityFixId = VF.Id
WHERE VAD_VF.VulnerabilityAlertDocumentId = 78385
That is, you are using the wrong column at your ON condition since VulnerabilityFixId seems to be the foreign key over VulnerabilityFix.Id and not VulnerabilityAlertDocumentId.
On the other hand, I can't see any VulnerabilityAlertDocument_VulnerabilityFix.VulnerabilityAlertDocumentId with value 1 in you data set (where condition)

Insert multi column result into single column table

I have a table 'movies' with three Columns: 'id', 'master_id' and 'searchMe' (simplified). I have another Table 'temp_ids' with a single column: 'id'. It is a temporary table, but I don't think that matters.
When I make a query on my table 'movies' like
SELECT `id`, `master_id` FROM 'movies' WHERE searchMe = '1';
I get a multi column result. Now I want to insert every id and every master_id into the 'temp_ids'-Table, but one at a time. So if my result is
id_1 | master_1
id_2 | master_2
id_3 | NULL
I want my temp_ids to look like
id_1
master_1
id_2
master_2
id_3
So I want to convert every single column in the result into its own row. How can I do that in an elegant way?
I know I can do it in multiple queries, searching for id and master_id separatly, and I know I can solve that problem with PHP or so. But I would prefer it to solve that problem in a single mysql-query, if such a thing is possible.
I made a sqlfiddle for this:
http://sqlfiddle.com/#!2/b4a7f/2
To SELECT the data you can use a UNION ALL for this:
SELECT `id`
FROM movies
WHERE searchMe = 1
union all
SELECT `master_id`
FROM movies
WHERE searchMe = 1
and master_id is not null
see SQL Fiddle with Demo
Doing it this way, you cannot distinguish between what value comes from each column, so you can always add an indicator, this will give you two columns but then you know where the data came from:
SELECT `id`, 'id' type
FROM movies
WHERE searchMe = 1
union all
SELECT `master_id`, 'master'
FROM movies
WHERE searchMe = 1
and master_id is not null
Then you would just use this query to INSERT INTO temp using this SELECT
It would be like this
INSERT INTO temp_ids(id)
SELECT id
FROM
(
SELECT id
FROM FirstTable
UNION
SELECT master AS id
FROM SecondTable
) t

sql query for deleting rows with NOT IN using 2 columns

I have a table with a composite key composed of 2 columns, say Name and ID. I have some service that gets me the keys (name, id combination) of the rows to keep, the rest i need to delete. If it was with only 1 row , I could use
delete from table_name where name not in (list_of_valid_names)
but how do I make the query so that I can say something like
name not in (valid_names) and id not in(valid_ids)
// this wont work since they separately dont identity a unique record or will it?
Use mysql's special "multiple value" in syntax:
delete from table_name
where (name, id) not in (select name, id from some_table where some_condition);
If your list is a literal list, you can still use this approach:
delete from table_name
where (name, id) not in (select 'john', 1 union select 'sally', 2);
Actually, no I retract my comment about needing special juice or being stuck with (AND OR'ing all your options).
Since you have a list of values of what you want to retain, dump that into a temporary table. Then do a delete against the base table for what does not exist in the temporary table (left outer join). I suck at mysql syntax or I'd cobble together your query. Psuedocode is approximate
DELETE
B
FROM
BASE B
LEFT OUTER JOIN
#RETAIN R
ON R.key1 = B.key1
AND R.key2 = B.key
WHERE
R.key1 IS NULL
The NOT EXISTS version:
DELETE
b
FROM
BaseTable b
WHERE
NOT EXISTS
( SELECT
*
FROM
RetainTable r
WHERE
(r.key1, r.key2) = (b.key1, b.key2)
)