I know there is more than one question out there that matches this, but I am relatively new to mysql, and I can't seem to make this work using sub quests or the USING key word, plus I find the mysql on line docs a complete mystery.
I started trying to build my DELETE query using a SELECT query as my base and was able to get all the rows that I wanted to delete:
select *
from writings_tags_link
join writing_tags on writing_tags.id = writings_tags_link.tag_id
where writing_tags.tag = 'tag one'
and then just replaced select all with DELETE so:
delete
from writings_tags_link
join writing_tags on writing_tags.id = writings_tags_link.tag_id
where writing_tags.tag = 'tag one'
I gather from both the error message and from other similar posts that you can't use 'ON' to join tables in a delete query, you have to use USING or a sub query. The query I built with USING returns a really strange error, first the query:
DELETE
FROM writings_tags_link
USING writing_tags_link INNER JOIN writing_tags
WHERE writing_tags.id = writings_tags_link.tag_id
AND writing_tags.tag ='tag one'
error:
#1109 - Unknown table 'writings_tags_link' in MULTI DELETE
This table does exist, obviously, my original select query returned the desired results. Any help / explanation would be so very appreciated!
Please keep in mind, I'm only trying to delete the data in the linking table.
Your information is incorrect about requiring the use of the USING keyword in DELETE syntax when using JOINs - the documentation provides examples in the multi-delete section:
DELETE wtl
FROM WRITINGS_TAGS_LINK wtl
JOIN WRITING_TAGS wt ON wt.id = wtl.tag_id
WHERE wt.tag = 'tag one'
Related
I am using laravel framework for developing API's ,i have one query that is executed without where condition without any error i need to execute with where condition but it's throwing an error
query
select count(*) as aggregate
from `users`
left join `books` on `books`.`book_id` = `books`.`id`
where `access_id` = 5054
SQL Error [1052] [23000]: Column 'access_id' in where clause is
ambiguous
after searching google i got something we have to specify reference of a table name , i added reference name like this where users.access_id =5054 but it's throwing an error like unknown column but in my db i have that column in both users and books table
The problem is its consider as a column so that's why syntax error is coming,try following way it will resolve your problem
select count(*) as aggregate
from `users`
left join `books` on `books`.`book_id` = `books`.`id`
where `users`.`access_id` = 5054
I'm trying to build an SQL-Query with MySQL-Version 5.7.27.
I'm trying to make multiple left joins to the same table. At some point i get an error, that tells me, a column of the original table is unknown.
I tried finding the syntax error in my query, but there can't seem to be an obvious one. I tried out some online SQL-validators. They keep telling me, my query is valid.
After that i tried picking apart the query, to find out, what exactly i am working with before the left join that makes my query unable to function. Doing that actually showed me a result, that was including the column the error was telling me, that is missing.
So maybe it is not a syntax error, but MySQL is validating things in a order different to what i know, trying to pick the "missing" column out of somewhere it actually doesn't exist.
Changing the order of left joins actually solves the problem. I can't really do that, tho. The SQL is being generated by some functions. One for every part of the SQL. One for the "SELECT", one for the "FROM" and so on. So a working thing is joining the minimized versions of the "additional_agreement_fields" table before the other joins. Sadly the function for the "FROM" part is written ... in a very interesting way. So my best bet is adding the "additional_agreement_fields" joins after the function that creates the FROM.
That attempt generated the SQL below.
I get following error:
Error Code: 1054. Unknown column 'customers.id' in 'on clause'
So:
- The parts of the query are working on their own
- Execution until the point of the error holds a table that has the
"missing column"
- Changing the order of the joins solves the problem, but i can't just
do that and i want to know, why it doesn't work in this order
- Online-validators can't find any syntax errors
- Logically i am just adding columns to a table that are not ambiguous
and not removing any. Yet something becomes unable to be found
SELECT DISTINCT
(customers.id),
companies.company_name AS 'Kunde -> Firmenname',
vcpt_mail.tcom_value AS 'Kontakt -> TCom -> Email',
v_contact_people.id AS 'Kontakt -> ID',
v_contact_people.last_name AS 'Kontakt -> Nachname',
A0.value AS 'Kunde -> Zusatzvereinbarung -> TestfeldB'
FROM
customers
LEFT JOIN
customer_types ON customer_types.id =
customers.customer_type_id,
v_customer_owners,
companies
LEFT JOIN
(v_contact_people
LEFT JOIN v_cp_tcoms AS vcpt_mail ON
vcpt_mail.contact_person_id = v_contact_people.id
AND vcpt_mail.ttid = 3
AND (vcpt_mail.type_label_access_path = '/Global'
OR vcpt_mail.type_label_access_path LIKE '/Global%')) ON
v_contact_people.company_id = companies.id
AND v_contact_people.access_path LIKE '/Global%'
LEFT JOIN
(SELECT
*
FROM
additional_agreement_fields
WHERE
name = 'TestfeldB' AND value = '5') AS A0 ON customers.id
= A0.customer_id
LEFT JOIN
(SELECT
*
FROM
additional_agreement_fields
WHERE
name = 'TestfeldC' AND value = '6') AS A1 ON customers.id
= A1.customer_id
WHERE
v_customer_owners.customer_id = customers.id
AND v_customer_owners.path LIKE '/Global%'
AND customers.company_id = companies.id
AND companies.deleted_at IS NULL
AND customers.deleted_at IS NULL
AND (A0.value = '5' AND A0.name = 'TestfeldB'
OR A1.value = '6' AND A1.name = 'TestfeldC');
The expected result is a not empty table with 2 customers in it, i prepared to find and that are found, changing the join order.
The result is an interrupted query with an error code.
Error Code: 1054. Unknown column 'customers.id' in 'on clause'
I have already read a majority of this similarly asked question but due to the specific nature of most of the answers, none helped, or I was unable to apply the answer.
I need to convert this SELECT statement into an UPDATE statement, the SELECT statement works just fine.
SELECT sf_state_filings_cstm.recurrency_c, sf_state_filings_cstm.date_filed_c,
sf_state_filings_cstm.status_c
FROM sc_state_configuration_cstm
INNER JOIN sc_state_configuration_sf_state_filings_1_c ON sc_state_configuration_cstm.id_c = sc_state_configuration_sf_state_filings_1_c.sc_state_c2445uration_ida
INNER JOIN sf_state_filings_cstm ON sc_state_configuration_sf_state_filings_1_c.sc_state_configuration_sf_state_filings_1sf_state_filings_idb = sf_state_filings_cstm.id_c
WHERE sc_state_configuration_cstm.id_c = '2d9b438e-01e1-ccb2-82e5-5721221114bb'
This is what I have so far after working through the following errors:
When I first wrote the update statement, I got:
MySQL code error 1066: Not unique table/alias: ‘sf_state_filings_cstm
Solution: Why does this SQL code give error 1066 (Not unique table/alias: 'user')?
Then I got this error:
1052: Column ‘recurrency_c' in field list is ambiguous
Solution: 1052: Column 'id' in field list is ambiguous
Now I have this error:
Error : Unknown column 'sc_state_configuration_cstm.id_c' in 'where
clause'
None of the below links have helped so far, or I was doing something wrong
Unknown Column In Where Clause
Unknown Column in Where Clause
MySQL: "Unknown column in where clause" during Update Statement
I have a feeling the answer has to do with using an alias as mentioned in one the links, using HAVING instead of WHERE, but just replacing WHERE with HAVING doesn't seem to work.
Here is my syntax right now:
UPDATE `my_database`.`sf_state_filings_cstm`
LEFT OUTER JOIN sc_state_configuration_sf_state_filings_1_c AS joined_tables ON sc_state_configuration_cstm.id_c = sc_state_configuration_sf_state_filings_1_c.sc_state_c2445uration_ida
LEFT OUTER JOIN sf_state_filings_cstm AS main_table ON sc_state_configuration_sf_state_filings_1_c.sc_state_configuration_sf_state_filings_1sf_state_filings_idb = sf_state_filings_cstm.id_c
SET main_table.recurrency_c = 'Perpetual',
main_table.expiration_date_c = ''
WHERE
sc_state_configuration_cstm.id_c = '2d9b438e-01e1-ccb2-82e5-5721221114bb'
EDIT 1:
Here is how the Tables have to be linked to each other:
I also realized, I need to be doing a LEFT OUTER JOIN instead of an INNER JOIN. I have updated the above syntax. The middle table stores the id's from both tables. That's how the relationship is stored. If more information is needed, let me know.
[SOLUTION]
UPDATE sc_state_configuration_cstm
LEFT OUTER JOIN sc_state_configuration_sf_state_filings_1_c ON sc_state_configuration_cstm.id_c = sc_state_configuration_sf_state_filings_1_c.sc_state_c2445uration_ida
LEFT OUTER JOIN sf_state_filings_cstm ON sc_state_configuration_sf_state_filings_1_c.sc_state_configuration_sf_state_filings_1sf_state_filings_idb = sf_state_filings_cstm.id_c
SET sf_state_filings_cstm.recurrency_c = 'Perpetual',
sf_state_filings_cstm.expiration_date_c = null
WHERE
sc_state_configuration_cstm.id_c = '2d9b438e-01e1-ccb2-82e5-5721221114bb'
Thanks to jyncka and a lot of other posts I read, where i noticed that when converting a SELECT to an UPDATE, they simply wrote UPDATE (table from the 'FROM' statement).
I went back and noticed I had written:
FROM sc_state_configuration_cstm
The error is telling you what's happening: id_c is not a column that exists in the sc_state_configuration_cstm table. If you do a DESCRIBE on sc_state_configuration_cstm it will show you the correct field name and you can drop that in instead of id_c.
Or you might have used the wrong alias in your WHERE statement. Without knowing what your tables look like, it's difficult to say which is the case.
Edit: I believe I see the problem. Here are the tables you are explicitly using in the statement:
sc_state_configuration_sf_state_filings_1_c
sf_state_filings_cstm
But you are using this table in the WHERE clause:
sc_state_configuration_cstm
You need to join sc_state_configuration_cstm so that it can be used. It took me a minute to see it because sc_state_configuration_cstm and sf_state_filings_cstm look similar at first glance.
I am tying to run an update query with a subquery against a MySQL database using ruby. I am using ruby 1.9.3 and rails 4.1.
The query I am trying to create is as below:
UPDATE `items`
SET
`items`.`status_id` = 12
WHERE
`items`.`id` IN (SELECT DISTINCT
`items`.`id`
FROM
`items`
LEFT OUTER JOIN
`statuses` ON `items`.`status_id` = `statuses`.`id`
LEFT OUTER JOIN
`resources` ON `items`.`resource_id` = `resources`.`id`
WHERE
`statuses`.`title` LIKE 'On Loan'
AND `items`.`duedate` < '2015-04-24'
AND `items`.`return_date` IS NULL
ORDER BY `items`.`duedate`)
I can produce this query in ruby using AREL with the code shown below:
# Declare Arel objects
i = Item.arel_table
s = Status.arel_table
r = Resource.arel_table
# This is the AREL query that returns the data
overdues = i.project(i[:id]).
join(s, Arel::Nodes::OuterJoin).on(i[:status_id].eq(s[:id])).
join(r, Arel::Nodes::OuterJoin).on(i[:resource_id].eq(r[:id])).
where(s[:title].matches("On Loan").
and(i[:duedate].lt(DateTime.now.to_date)).
and(i[:return_date].eq(nil))
).
order(i[:duedate])
# Note: You can't chain distinct, otherwise "overdues" becomes a string with the value "DISTINCT".
overdues.distinct
# This creates the update...
u = Arel::UpdateManager.new i.engine
u.table(i)
u.set([[i[:status_id], 10]]).where(i[:id].in(overdues))
This does not work and returns an error message:
ActiveRecord::StatementInvalid: Mysql2::Error: You can't specify target table 'items' for update in FROM clause:
I tried using AR "update_all" but it produces the same SQL and hence the same error.
Item.where(i[:id].in(overdues)).update_all(:status_id => (Status.find_by(:title => "Overdue").id))
Having done some research I have found that you cannot run a update with a subquery that references the table you want to update in MySQL. I have seen a number of posts on this site and the wider internet that detail work arounds.
One suggestion says that the update should use a join instead of a sub query. Having looked at the code behind the update manager it has no "join" so I can't do that.
Another says run this in two parts but I can't see how to because AREL and AciveRecord both chain actions.
The only way I can see of doing this is by aliasing the table and adding an additional select (see below). This isn't great but it would be useful to see if it is possible to do.
UPDATE `items`
SET `status_id` = 10
WHERE `items`.`id` IN (
SELECT x.id
FROM
(SELECT DISTINCT `items`.`id`
FROM `items`
LEFT OUTER JOIN `statuses` ON `items`.`status_id` = `statuses`.`id`
LEFT OUTER JOIN `resources` ON `items`.`resource_id` = `resources`.`id`
WHERE `statuses`.`title` LIKE 'On Loan'
AND `items`.`duedate` < '2015-04-24'
AND `items`.`return_date` IS NULL
ORDER BY `items`.`duedate`) x
);
If I can't get this to work I could adopt two other approaches:
1) I could just hard-code the SQL but I want to use ActiveRecord and reference the models to keep it database agnostic.
2) The other way is to return an instance of all the records and loop through them doing individual updates. This will have a performance issue but I can accept this because its a background job that won't be updating more than a handful of records each day.
Update
I have the AREL query below that produces the subquery in the format I need.
x = Arel::Table.new('x')
overdues = Item.select(x[:id]).from(
Item.select(Item.arel_table[:id]).where(
Status.arel_table[:title].matches("On Loan").and(
Item.arel_table[:duedate].lt(DateTime.now.to_date).and(
Item.arel_table[:return_date].eq(nil))
)
).joins(
Item.arel_table.join(Status.arel_table, Arel::Nodes::OuterJoin).on(
Item.arel_table[:status_id].eq(Status.arel_table[:id])
).join_sources
).joins(
Item.arel_table.join(Resource.arel_table, Arel::Nodes::OuterJoin).on(
Item.arel_table[:resource_id].eq(Resource.arel_table[:id])
).join_sources
).order(Item.arel_table[:duedate]).uniq.as('x')
)
Sadly it returns an error when I use it in my update statement.
TypeError: Cannot visit Item::ActiveRecord_Relation
Having revisited this question I am at the conclusion that it's not possible to do this because of a limitation with MySQL:
ActiveRecord::StatementInvalid: Mysql2::Error: You can't specify target table 'items' for update in FROM clause:
It should be possible to do with other databases (although I haven't tested that).
I could create a temporary table, which is the copy of the original table, reference that and then drop the temporary table like this post suggests:
http://richtextblog.blogspot.co.uk/2007/09/mysql-temporary-tables-and-rails.html. That seems a lot of overhead to do a simple subquery.
What I am going to do is find all the ID's and loop through them and update the records that way (using a simple find and update). This has an overhead but it should only be updating a handful of records each run (no more than 100). The update will be running as a scheduled job outside user working hours so it won't impact performance.
I still find it bizarre that in all other flavours of SQL I have never encountered this problem before. Still you live and learn.
UPDATE:
Since updating my version of MySQL the select statement now works. I had to take out the order by for it to work.
ORDER BY `items`.`duedate`
I am now using version: 5.7.19.
I have the following query in HQL:
update ProjectFile pf1
set pf1.validUntil.id =123
where pf1 = (
select pf from ProjectVersion pv, ProjectFile as pf
where pf.validFrom.sequence <= pv.sequence
and pf.validUntil.sequence >= pv.sequence
and pf.state <> 12
and pf.projectVersion.project.id = 1
and pv.project.id = 1
and pv.id = 12
and pf.id not in (2,3,4)
)
Hibernate parses the query correctly and generates SQL, but the database (MySQL) fails with error:
You can't specify target table 'ProjectFile' for update in FROM clause
The problem seems to be that the table to be updated is queried in the same context. Is there any way to rewrite the HQL query to produce SQL that can be executed in MySQL correctly? The other approach would be to create an intermediate table, which is what exactly I am trying to avoid.
I bumped into the same problem and posted a question here: MySQL/SQL: Update with correlated subquery from the updated table itself.
To solve your problem, you need to join at the UPDATE level, please take a look at the answer to my question.