how to use a dynamic inner column outside the select - mysql

i have this query and i get error in mysql
Error Code: 1054. Unknown column 'calc_diff_free' in 'field list'
I understand the problem, but how can i use this column without changing too much
I filtered the query to hide some data and to help you guys to read the query better
insert into ranking_1 (difference_free)
(
select
f.ranking, rc.ranking,
(-1*(f.ranking-rc.ranking)) as calc_diff_free
from base_testing.ranking_temp f
left join ranking_1 rc
on f.id=rc.id
where 1
)
on duplicate key update difference_free=calc_diff_free
Thanks for your help!!

The on duplicate key update clause in your query is outside the scope of the select item where the column calc_diff_free is declared.
You may need to recast your query to put it in scope.

try something like this,
insert into ranking_1 (difference_free)
select -1 * (f.ranking-rc.ranking) as calc_diff_free
from base_testing.ranking_temp f
left join ranking_1 rc
on f.id=rc.id
on duplicate key update difference_free = calc_diff_free
Point: you must have equal number of columns in your insert and select clause.

I think i manage to get it working...
insert into ranking_1 (difference_free)
(
select
f.ranking, rc.ranking,
(-1 * (f.ranking-rc.ranking)) calc_diff_free
from base_testing.ranking_temp f
left join ranking_1 rc
on f.id=rc.id
where 1
)
on duplicate key update difference_free=-1*(f.ranking-rc.ranking)
But it's give me a few warnings...
85672 row(s) affected,Records: 42883, Duplicates: 42789, Warnings: 4

Related

MySQL - Update Select Issues

The aim of my query is to use a value from one table A to look up a corresponding value from another table B, and then use that value to look up another value from another table C. This value should then be used to update a column in the original table A.
In my query so far I have managed to get a correct list of the values from table C using this command. In this command, Disbursements, Employee_Details & List_State_Codes correspond to tables A, B & C respectively as described above.
SELECT `List_State_Codes`.`Code`
FROM `List_State_Codes`
LEFT JOIN (
`Employee_Details` , `Disbursements`
) ON ( `Employee_Details`.`STATE` = `List_State_Codes`.`STATE` )
WHERE `Employee_Details`.`EmployeeID` = `Disbursements`.`EmployeeID`
This returns the correct list of values as required: One value from table C for each row in table A. Now my issue is to update the required column from table A with these returned values. This is where I am stuck.
The following query is what I believe to be my closest attempt:
UPDATE `Disbursements`
SET `Disbursements`.`CostCentreID` =
(
SELECT `List_State_Codes`.`Code`
FROM (SELECT * FROM `List_State_Codes`) AS `table`
LEFT JOIN (
`Employee_Details` , `Disbursements`
) ON ( `Employee_Details`.`STATE` = `List_State_Codes`.`STATE` )
WHERE `Employee_Details`.`EmployeeID` = `Disbursements`.`EmployeeID`
)
I receive the
error #1093 - You can't specify target table 'Disbursements' for update in FROM clause, despite adding the FROM (SELECT * FROM List_State_Codes) AS table line.
Thanks for any help.
You can join in the update, and this can help to remove the offending table from the subquery:
UPDATE `Disbursements`
JOIN `Employee_Details`
ON `Employee_Details`.`EmployeeID` = `Disbursements`.`EmployeeID`
LEFT JOIN `List_State_Codes`
ON `Employee_Details`.`STATE` = `List_State_Codes`.`STATE`
SET `Disbursements`.`CostCentreID` = `List_State_Codes`.`Code`
However, I could not test this, so let me know if this helps. (or if some other error occurs)
Thanks to Paul's help I have found the correct solution to my problem. The second join was what I needed as Paul suggested, along with an additional table alias to prevent the classic #Error 1903. I also needed to add the List_State_Codes (table C) to the JOIN to ensure it could access the correct data.
UPDATE `Disbursements`
JOIN `Employee_Details`
ON `Employee_Details`.`EmployeeID` = `Disbursements`.`EmployeeID`
LEFT JOIN (
`Employee_Details` d,
`List_State_Codes`
) ON
`Employee_Details`.`STATE` = `List_State_Codes`.`STATE`
SET `Disbursements`.`CostCentreID` = `List_State_Codes`.`Code`

Unknown column in 'where-clause'

I have simple sql:
SELECT *
FROM `oc_artists`
WHERE `oc_artists`.`artist_id`=`oc_artists_tags`.`artist_id`
AND `oc_artists_tags`.`artist_tag` LIKE '%klass%'
When I run this I got:
1054 - Unknown column 'oc_artists_tags.artist_id' in 'where clause'
This is a sql for a search script. I need simple return unique results from oc_artists if query matches with oc_artists_tags.artist_tag.
You need to JOIN the table oc_artists_tags too and you can achieve this two way,
Option 1
SELECT *
FROM `oc_artists`
INNER JOIN `test2` on `oc_artists`.`artist_id`=`oc_artists_tags`.`artist_id`
AND `oc_artists_tags`.`artist_tag` LIKE '%klass%'
Option 2
SELECT *
FROM `oc_artists`,`oc_artists_tags`
WHERE `oc_artists`.`artist_id`=`oc_artists_tags`.`artist_id`
AND `oc_artists_tags`.`artist_tag` LIKE '%klass%'
2nd join table is missing from your query, so include oc_artists_tags table in your join...
Finally your query should be-
SELECT *
FROM `oc_artists`, `oc_artists_tags`
WHERE `oc_artists`.`artist_id`=`oc_artists_tags`.`artist_id`
AND `oc_artists_tags`.`artist_tag` LIKE '%klass%'
You can also use join or inner join instead of comma join-
SELECT *
FROM `oc_artists` as oa
join `oc_artists_tags` as oat on oa.artist_id=oat.artist_id
WHERE oat.artist_tag LIKE '%klass%';
To gain performance follow below points-
You should select only required columns instead of *.
join fields must be indexed and better will be that these fields should be integer type.
If possible avoid '%'in left side in like clause as it will not use index and slow your query. for example artist_tag like 'klass%' will use index but '%klass%' will not.
You have to join the other table.Join helps you.

Mysql error 1093 - Can't specify target table for update in FROM clause - update column in same table

I know there are a lot of topics on this but I can't figure out how should I rewrite my query to make it work :(
Here my query. It's just should take currency rate from other table and calculate cost
update site_s_client_base_price
SET calculated_price_in_base_currency =
SELECT (site_s_currencies.rate * site_s_client_base_price.supplier_price) from
site_s_currencies, site_s_client_base_price
WHERE site_s_currencies.currency_id=site_s_client_base_price.currency_id
Please, help me with this
You can't seletc and update in the same table because it's locked, use the example above or use
Update TABLE1 t1 set FIELD1= ( select field1 from TABLE1 t2 where .....)
In your case you can fix this by fixing the subquery. You don't need to mention the outer table in the inner from clause. You want a correlated subquery:
update site_s_client_base_price bp
SET calculated_price_in_base_currency =
(SELECT c.rate * bp.supplier_price
FROM site_s_currencies c
WHERE c.currency_id = bp.currency_id
);

Delete values in one table based on values in another table

I was trying to execute this statement to delete records from the F30026 table that followed the rules listed.. I'm able to run a select * from and a select count(*) from with that statement, but when running it with a delete it doesn't like it.. it gets lost on the 'a' that is to define F30026 as table a
delete from CRPDTA.F30026 a
where exists (
select b.IMLITM from CRPDTA.F4101 b
where a.IELITM=b.IMLITM
and substring(b.IMGLPT,1,2) not in ('FG','IN','RM'));
Thanks!
This looks like an inner join to me, see MySQL - DELETE Syntax
delete a from CRPDTA.F30026 as a
inner join CRPDTA.F4101 as b on a.IELITM = b.IMLITM
where substring(b.IMGLPT, 1, 2) not in ('FG', 'IN', 'RM')
Please note the alias syntax as a and as b.
Instead of the 'exists' function, you can match the id (like you do in the where clause):
delete from CRPDTA.F30026 a
where a.IELITM IN (
select b.IMLITM from CRPDTA.F4101 b
where a.IELITM=b.IMLITM
and substring(b.IMGLPT,1,2) not in ('FG','IN','RM'));
I believe this is what you really want, all IELITMs which meet your criteria.
delete from CRPDTA.F30026
where IELITM IN (
select IMLITM from CRPDTA.F4101
where substring(IMGLPT,1,2) not in ('FG','IN','RM'));

subquery in where clause of UPDATE statement

I have the database of ATM card in which there are fields account_no,card_no,is_blocked,is_activated,issue_date
Fields account number and card numbers are not unique as old card will be expired and marked as is_block=Y and another record with same card number ,account number will be inserted into new row with is_blocked=N . Now i need to update is_blocked/is_activated with help of issue_date i.e
UPDATE card_info set is_blocked='Y' where card_no='6396163270002509'
AND opening_date=(SELECT MAX(opening_date) FROM card_info WHERE card_no='6396163270002509')
but is doesn't allow me to do so
it throws following error
1093 - You can't specify target table 'card_info' for update in FROM clause
Try this instead:
UPDATE card_info ci
INNER JOIN
(
SELECT card_no, MAX(opening_date) MaxOpeningDate
FROM card_info
GROUP BY card_no
) cm ON ci.card_no = cm.card_no AND ci.opening_date = cm.MaxOpeningDate
SET ci.is_blocked='Y'
WHERE ci.card_no = '6396163270002509'
That's one of those stupid limitations of the MySQL parser. The usual way to solve this is to use a JOIN query as Mahmoud has shown.
The (at least to me) surprising part is that it really seems a parser problem, not a problem of the engine itself because if you wrap the sub-select into a derived table, this does work:
UPDATE card_info
SET is_blocked='Y'
WHERE card_no = '6396163270002509'
AND opening_date = ( select max_date
from (
SELECT MAX(opening_date) as_max_date
FROM card_info
WHERE card_no='6396163270002509') t
)