Table will not update when new data is populated in the view. The query runs with no error, but the table is not updated. I'm trying to update the table with data from the view that is not already in the table, based upon the shipping id.
INSERT INTO `table`(`store`, `shippingid`)
SELECT store,shipment_id FROM view WHERE NOT EXISTS (SELECT `shippingid` FROM `table`)
You have to include the correlation between the view and your table:
INSERT INTO `table`(`store`, `shippingid`)
SELECT store,shipment_id
FROM view
WHERE NOT EXISTS (SELECT `shippingid`
FROM `table`
WHERE shippingid = view.shipment_id)
Please note that this query is an INSERT operation, not an UPDATE.
If you have any row in your table this will always be false:
WHERE NOT EXISTS (SELECT `shippingid` FROM `table`)
It seems you might need to add correlation:
WHERE NOT EXISTS (SELECT `shippingid` FROM `table` WHERE shippingid = view.shipment_id)
Please note that, theoretically, sub-queries execute once for every row of outer query. So to understand the flow.. take some sample data and understand how the query will produce results.
Related
I have a table with many columns in SQL Server and I have move part of data into MySQL. I made a view or function on the table in SQL Server and these two databases must be synced once a day through job. Because the data of this view may change every day.
View return a table with 3 columns: (char, varchar, varchar) that none of them are unique or primary key.
My solution is:
create a job
execute view on SQL Server
return result of view
create temp table with 3 column in MySQL
move result view from SQL Server to temp table
move records from temp table to new table one by one if not exist before
delete temp table
To transfer without using the temp table, I wanted to use below type of query but could not find the correct query. That's why I used the temp table:
insert into new_table
values (array of records) where record if not exist in new table.
And for the solution I mentioned above, I used the following query:
insert into new_table
select *
from temp_table
where not exist new_table.column = temp_table.column
Do you have a better suggestion that new records can be fetch and added to previous records?
It should look more like this:
insert into new_table
select *
from temp_table
where not exists (
select 1
from new_table
where new_table.column = temp_table.column
)
or maybe this:
insert into new_table
select *
from temp_table
where not exists (
select 1
from new_table
where new_table.column = temp_table.column
and new_table.column2 = temp_table.column2
and new_table.column3 = temp_table.column3
)
I have two tables ,location and locationdata. I want to query data from both the tables using join and to store the result in a new table(locationCreatedNew) which is not already present in the MySQL.Can I do this in MySQL?
SELECT location.id,locationdata.name INTO locationCreatedNew FROM
location RIGHT JOIN locationdata ON
location.id=locationdata.location_location_id;
Your sample code in OP is syntax in SQL Server, the counter part of that in MySQL is something like:
CREATE TABLE locationCreatedNew
SELECT * FROM location RIGHT JOIN locationdata
ON location.id=locationdata.location_location_id;
Referance: CREATE TABLE ... SELECT
For CREATE TABLE ... SELECT, the destination table does not preserve information about whether columns in the selected-from table are generated columns. The SELECT part of the statement cannot assign values to generated columns in the destination table.
Some conversion of data types might occur. For example, the AUTO_INCREMENT attribute is not preserved, and VARCHAR columns can become CHAR columns. Retrained attributes are NULL (or NOT NULL) and, for those columns that have them, CHARACTER SET, COLLATION, COMMENT, and the DEFAULT clause.
When creating a table with CREATE TABLE ... SELECT, make sure to alias any function calls or expressions in the query. If you do not, the CREATE statement might fail or result in undesirable column names.
CREATE TABLE newTbl
SELECT tbl1.clm, COUNT(tbl2.tbl1_id) AS number_of_recs_tbl2
FROM tbl1 LEFT JOIN tbl2 ON tbl1.id = tbl2.tbl1_id
GROUP BY tbl1.id;
NOTE: newTbl is the name of the new table you want to create. You can use SELECT * FROM othertable which is the query that returns the data the table should be created from.
You can also explicitly specify the data type for a column in the created table:
CREATE TABLE foo (a TINYINT NOT NULL) SELECT b+1 AS a FROM bar;
For CREATE TABLE ... SELECT, if IF NOT EXISTS is given and the target table exists, nothing is inserted into the destination table, and the statement is not logged.
To ensure that the binary log can be used to re-create the original tables, MySQL does not permit concurrent inserts during CREATE TABLE ... SELECT.
You cannot use FOR UPDATE as part of the SELECT in a statement such as CREATE TABLE new_table SELECT ... FROM old_table .... If you attempt to do so, the statement fails.
Please check it for more. Hope this help you.
Use Query like below.
create table new_tbl as
select col1, col2, col3 from old_tbl t1, old_tbl t2
where condition;
I'm using MySQL Stored Procedures and I want to insert some rows from a table's database to another table's database through a stored procedure. More specifically from database "new_schema", table "Routers" and field "mac_address" to database "data_warehouse2", table "dim_cpe" and field "mac_address".
This is the code I used in the first insertion, that worked perfectly.
insert into data_warehouse2.dim_cpe (data_warehouse2.dim_cpe.mac_address, data_warehouse2.dim_cpe.ssid)
(select new_schema.Routers.mac_address, new_schema.Routers.ssid from new_schema.Routers, data_warehouse2.dim_cpe);
Now I have more rows in the table "Routers" to be inserted into "dim_cpe" but, since there are rows already there, I want just to insert the new ones.
As seen in other posts, I tried a where clause:
where new_schema.device_info.mac_address != data_warehouse2.dim_cpe.mac_address
and a:
on duplicate key update new_schema.Routers.mac_address = data_warehouse2.dim_cpe.mac_address"
Both didn't work. What's the best way to do this?
Thanks in advance.
You could leave the source table out of the from clause, and use a not exists clause instead:
where not exists
(select mac_address from dim_cpe mac_address = new_schema.Routers.mac_address
and ssid = new_schema.Routers.ssid)
Or you could left join and check whether the fields from dim_cpe are null:
insert into data_warehouse2.dim_cpe
(data_warehouse2.dim_cpe.mac_address, data_warehouse2.dim_cpe.ssid)
(select new_schema.Routers.mac_address, new_schema.Routers.ssid
from new_schema.Routers
left join data_warehouse2.dim_cpe on
new_schema.Routers.mac_address = data_warehouse2.dim_cpe.mac_address
and new_schema.Routers.ssid = data_warehouse2.dim_cpe.ssid
where dim_cpe.mac_address is null and dim_cpe.ssid is null);
Edit to say this is a general SQL solution. I'm not sure if there's a better MySql-specific approach to this.
Edit to show your query:
insert into data_warehouse2.dim_cpe (mac_address, ssid)
select new_schema.Routers.mac_address, new_schema.Routers.ssid
from new_schema.Routers where not exists
(select data_warehouse2.dim_cpe.mac_address from data_warehouse2.dim_cpe
where data_warehouse2.dim_cpe.mac_address = new_schema.Routers.mac_address
and data_warehouse2.dim_cpe.ssid = new_schema.Routers.ssid);
EDIT I don't have CREATE TEMPORARY TABLE permissions. Is there another way?
A MySQL database has a table User which contains an id column.
Another table is UserThing which has a user column which is a foreign key to User.id
I am trying to insert one row into UserThing for certain rows in User, like this.
INSERT INTO `UserThing` (`user`, `foo`, `bar`)
SELECT `id`, 123, 456 FROM `User` WHERE some_condition;
I'm pretty sure this is okay except that there is a trigger on UserThing which potentially updates a column in User. This creates a dependency loop which MySql doesn't allow, although I know that this trigger's action is orthogonal to some_condition so it doesn't matter in practice.
I know I can write SELECT #some_var := ... for single values, but I can't make it work for multiple values. Is a local variable the right way to fix this? If so, what is the syntax, please? If not, is there some other pure-SQL way to do this?
I would use a temporary table and break them INSERT INTO ... SELECT FROM into the following statements:
SELECT `id`, 123, 456 INTO #tmp FROM `User` WHERE some_condition;
INSERT INTO `UserThing` (`user`, `foo`, `bar`)
SELECT * FROM #tmp
DROP TABLE #tmp
I need to query a delete statement for the same table based on column conditions from the same table for a correlated subquery.
I can't directly run a delete statement and check a condition for the same table in mysql for a correlated subquery.
I want to know whether using temp table will affect mysql's memory/performance?
Any help will be highly appreciated.
Thanks.
You can make mysql do the temp table for you by wrapping your "where" query as an inline from table.
This original query will give you the dreaded "You can't specify target table for update in FROM clause":
DELETE FROM sametable
WHERE id IN (
SELECT id FROM sametable WHERE stuff=true
)
Rewriting it to use inline temp becomes...
DELETE FROM sametable
WHERE id IN (
SELECT implicitTemp.id from (SELECT id FROM sametable WHERE stuff=true) implicitTemp
)
Your question is really not clear, but I would guess you have a correlated subquery and you're having trouble doing a SELECT from the same table that is locked by the DELETE. For instance to delete all but the most recent revision of a document:
DELETE FROM document_revisions d1 WHERE edit_date <
(SELECT MAX(edit_date) FROM document_revisions d2
WHERE d2.document_id = d1.document_id);
This is a problem for MySQL.
Many examples of these types of problems can be solved using MySQL multi-table delete syntax:
DELETE d1 FROM document_revisions d1 JOIN document_revisions d2
ON d1.document_id = d2.document_id AND d1.edit_date < d2.edit_date;
But these solutions are best designed on a case-by-case basis, so if you edit your question and be more specific about the problem you're trying to solve, perhaps we can help you.
In other cases you may be right, using a temp table is the simplest solution.
can't directly run a delete statement and check a condition for the same table
Sure you can. If you want to delete from table1 while checking the condition that col1 = 'somevalue', you could do this:
DELETE
FROM table1
WHERE col1 = 'somevalue'
EDIT
To delete using a correlated subquery, please see the following example:
create table project (id int);
create table emp_project (id int, project_id int);
insert into project values (1);
insert into project values (2);
insert into emp_project values (100, 1);
insert into emp_project values (200, 1);
/* Delete any project record that doesn't have associated emp_project records */
DELETE
FROM project
WHERE NOT EXISTS
(SELECT *
FROM emp_project e
WHERE e.project_id = project.id);
/* project 2 doesn't have any emp_project records, so it was deleted, now
we have 1 project record remaining */
SELECT * FROM project;
Result:
id
1
Create a temp table with the values you want to delete, then join it to the table while deleting. In this example I have a table "Games" with an ID column. I will delete ids greater than 3. I will gather the targets in a temp table first so I can report on them later.
DECLARE #DeletedRows TABLE (ID int)
insert
#DeletedRows
(ID)
select
ID
from
Games
where
ID > 3
DELETE
Games
from
Games g
join
#DeletedRows x
on x.ID = g.ID
I have used group by aggregate with having clause and same table, where the query was like
DELETE
FROM TableName
WHERE id in
(select implicitTable.id
FROM (
SELECT id
FROM `TableName`
GROUP by id
HAVING count(id)>1
) as implicitTable
)
You mean something like:
DELETE FROM table WHERE someColumn = "someValue";
?
This is definitely possible, read about the DELETE syntax in the reference manual.
You can delete from same table. Delete statement is as follows
DELETE FROM table_name
WHERE some_column=some_value