I can't find out if the below is possible. I want to run an update statement in one database from another database. I know that I can save a query and run that from the master database but I thought the below would be possible
UPDATE tblOne
INNER JOIN tblTwo
ON tblOne.[TID] = tblTwo.TID
SET tblTwo.PC = [tblOne].[PC]
from tblOne in 'C:\DB.mdb' ;
Any help would be greatly appreciated
Per the MSDN Documentation, the IN clause is only compatible when used in conjunction with the SELECT statement (i.e. Select queries), INSERT INTO statement (i.e. Append queries), or SELECT INTO statement (i.e. Make Table queries) - it cannot be used as part of an UPDATE statement.
I would suggest that you import tblOne as a linked table in the database in which you intend to execute your UPDATE query - this will also result in improved performance over the use of the IN clause.
To link the table, select Access Database from the Import panel of the External Data ribbon tab, and then select the Link option from the wizard:
After the table has been linked, your UPDATE statement will become simply:
UPDATE
tblOne INNER JOIN tblTwo ON tblOne.TID = tblTwo.TID
SET
tblTwo.PC = tblOne.PC
I think you just need to reverse what you’ve written because the table you’re updating needs to be the main table.
Try:
UPDATE tblTwo
INNER JOIN tblOne ON tblOne.[TID] = tblTwo.TID
SET tblTwo.PC = [tblOne].[PC] ;
Please note without a where clause you will be updating all rows.
Related
I have an update statement which I thought should update some records, but it doesn't. I'm using MySQL 5.5.46.
How can I determine which INNER JOIN or WHERE clauses are preventing it?
Very easy method is to change UPDATE into SELECT, and see the results of your SELECT-query. When you are satisfied with your INNER JOIN modifications by getting the correct records that you want to update, just change SELECT back into UPDATE to realize your record-update. Success.
I'm currently using the following to update a table of mine:
UPDATE Check_Dictionary
SET InDict = "No" WHERE (Leagues, Matches, Line) IN (SELECT * FROM (
SELECT Leagues, Matches, Line FROM Check_Dictionary
WHERE InDict = "No")as X)
However, when I have large data sets (40k+ rows) this seems to be fairly inefficient/slow. All of the searching I'm doing suggests that joins are far more efficient for this sort of thing than a sub-query. However, being a mysql newbie I'm not sure of the best way to do it.
My table may have multiple rows where the League/Matches/Line fields are the same. Generally the InDict field on these rows will be "Yes". However, if one of them is "No" I need to update all of the other rows with the same League/Matches/Line columns to "No" as well (so they all have a value of "No").
Would using a join in Mysql update statement instead of sub-query be more efficient?
How can I do it using a join?
I would think a join should be faster, but it depends on indexing and other things, you should try it for yourself to see which performs better (and maybe use explain to analyze the queries).
As for syntax, any of these should work:
UPDATE Check_Dictionary c1
JOIN (
SELECT Leagues, Matches, Line
FROM Check_Dictionary
WHERE InDict = "No"
) AS X USING (Leagues, Matches, Line)
SET InDict = "No"
UPDATE Check_Dictionary AS c1
JOIN Check_Dictionary AS c2 USING (Leagues, Matches, Line)
SET c1.InDict = "No"
WHERE c2.InDict = "No"
The update join query given by "jpw" was correct you can use it, I don't want to repeat. Having said, i just want to post join is faster than subquery obviously especially if you want to update 40K+ rows. Below is the data from MySQL documentation says about the same.
A LEFT [OUTER] JOIN can be faster than an equivalent subquery because the server might be able to optimize it better—a fact that is not specific to MySQL Server alone. Prior to SQL-92, outer joins did not exist, so subqueries were the only way to do certain things. Today, MySQL Server and many other modern database systems offer a wide range of outer join types.
MySQL Server supports multiple-table DELETE statements that can be used to efficiently delete rows based on information from one table or even from many tables at the same time. Multiple-table UPDATE statements are also supported. See Section 13.2.2, “DELETE Syntax”, and Section 13.2.10, “UPDATE Syntax”.
Source : http://dev.mysql.com/doc/refman/5.1/en/rewriting-subqueries.html
I have a select shown below that brings back the correct count per "sender_userid".
I want to insert this into a table in another database where there is a matching column "userid".
I'm not sure how to get the WHERE clause to work when used across database.
I've tried database.table.column but this appears wrong.
Is this possible? thx
WHERE statements must come before ORDER BY and GROUP BY statements. Also you should use the ON operator. Try this:
INSERT INTO dating_users.statistics (messages_sent)
SELECT COUNT(pid) FROM dating_messages.messages M
JOIN dating_users.statistics S
ON (S.userid = M.sender_userid)
GROUP BY sender_userid ORDER BY sender_userid ASC;
Edit: sorry I didn't realize that you were missing your actual JOIN statement. Just because you are INSERTing into a table doesn't make any data accessible from that table. You still need to JOIN to it.
Using a UPDATE query, is it possible to reference to a stored select query?
I'd like to accomplish something like this:
UPDATE ... WHERE ... IN [MY_STORED_PROCEDURE]
Perhaps something on these lines:
UPDATE ...
WHERE ID IN (SELECT ID FROM MyStoredProc)
Depending on your set up, a join may also be possible. You can add stored queries to the query design window, but you do not always end up with an updatable query, it usually depends on your indexes.
So I have a couple SQL commands that I basically want to make a proc, but while doing this, I'd like to optimize them a little bit more.
The first part of it is this:
select tr_reference_nbr
from cfo_daily_trans_hist
inner join cfo_fas157_valuation on fv_dh_daily_trans_hist_id = dh_daily_trans_hist_id
inner join cfo_tran_quote on tq_tran_quote_id = dh_tq_tran_quote_id
inner join cfo_transaction on tq_tr_transaction_id = tr_transaction_id
inner join cfo_fas157_project_valuation ON fpv_fas157_project_valuation_id = fv_fpv_fas157_project_valuation_id AND fpv_status_bit = 1
group by tr_reference_nbr, fv_dh_daily_trans_hist_id
having count(*)>1
This query returns to me which tr_reference_nbr's exist that have duplicate data in our system, which needs to be removed. After this is run, I run this other query, copying and pasting in the tr_reference_nbr one at a time that the above query gave me:
select
tr_reference_nbr , dh_daily_trans_hist_id ,cfo_fas157_project_valuation.*,
cfo_daily_trans_hist.* ,
cfo_fas157_valuation.*
from cfo_daily_trans_hist
inner join cfo_fas157_valuation on fv_dh_daily_trans_hist_id = dh_daily_trans_hist_id
inner join cfo_tran_quote on tq_tran_quote_id = dh_tq_tran_quote_id
inner join cfo_transaction on tq_tr_transaction_id = tr_transaction_id
iNNER JOIN cfo_fas157_project_valuation ON fpv_fas157_project_valuation_id = fv_fpv_fas157_project_valuation_id
where
tr_reference_nbr in
(
[PASTEDREFERENCENUMBER]
)
and fpv_status_bit = 1
order by dh_val_time_stamp desc
Now this query gives me a bunch of records for that specific tr_reference_nbr. I then have to look through this data and find the rows that have a matching (duplicate) dh_daily_trans_hist_id. Once this is found, I look and make sure that the following columns also match for that row so I know they are true duplicates: fpv_unadjusted_sponsor_charge, fpv_adjusted_sponsor_charge, fpv_unadjusted_counterparty_charge, and fpv_adjusted_counterparty_charge.
If THOSE all match, I then look to yet another column, fv_create_dt, and make sure that there is less then a minute difference between the two timestamps there. If there is, I run yet another query on the row that was stored EARLIER, which looks like this:
begin tran
update cfo_fas157_valuation set fpv_status_bit = 0 where fpv_fas157_project_valuation_id = [IDRECIEVEDFROMTHEOTHERTABLE]
commit
As you can see, this is still a very manual process even though we do have a few queries written, but I'm trying to find a solution to where we can just run one query, and it would basically do EVERYTHING except for the final query. So basically something that would provide to us a few fpv_fas157_project_valuation_id's that need to be updated.
From looking at these queries, do any of you guys see an easy way to combine all this? I've been working on it all day and can't seem to get something to run. I feel like I keep screwing up the joins and stuff.
Thanks!
You can combine these queries in multiple ways:
use temporary tables to store results of queries - suitable for stored procedure
use table variables to store results of queries - suitable for stored procedure
use Common Table Expressions (CTEs) to store results of queries - suitable for single query
Once You have them in separate tables/variables/CTEs You can easily join them.
Then You have to do one more thing, and that is to find difference in datetime in two consecutive rows. There is a trick to do this:
use ROW_NUMBER() to add a column with number of row partitioned by grouping fields (tr_reference_nbr, ... ) ordered by fv_create_dt
do a self join on A.ROW_NUMBER = B.ROW_NUMBER + 1
check the difference between A.fv_create_dt and B.fv_create_dt to filter the rows with difference less than a minute
Just do a good test of your self-join to make sure You filter only rows You need to filter.
If You still have problems with this, don't hesitate to leave a comment.
Interesting note: SQL Server Denali has T-SQL enhancements LEAD and LAG to access subsequent and previous row without self-joins.