Update with Subquery non relational table - mysql

I have the follow sql query but when I execute It gives me a message error: Unknown column 't1.ip' in 'where clause'.
If I hard code t1.ip in subquery just for testing, It works perfectly.
UPDATE
report_a t1,
(SELECT
location.country, region.name, location.city
FROM
geoip
INNER JOIN
location
ON
geoip.locId = location.locId
INNER JOIN
region
ON
region.country = location.country
AND
region.region = location.region
WHERE
INET_ATON(t1.ip) BETWEEN startIpNum AND endIpNum
LIMIT 1) AS t2
SET
t1.country = t2.country,
t1.city = t2.city,
t1.state = t2.name;
Someone have any idea how i can do this query?
Thanks

You are looking for a join. I am a bit unclear on what the LIMIT 1 is supposed to be doing. I moved that into the outer query, although that might not be correct:
UPDATE report_a t1,
(SELECT location.country, region.name, location.city, startIpNum, endIpNum
FROM geoip INNER JOIN
location
ON geoip.locId = location.locId INNER JOIN
region
ON region.country = location.country AND
region.region = location.region
) glr
ON INET_ATON(t1.ip) BETWEEN glr.startIpNum AND glr.endIpNum
SET t1.country = t2.country,
t1.city = t2.city,
t1.state = t2.name
LIMIT 1;
As I think about it, you probably do not want the LIMIT 1. Why would there be multiple matches to the subquery?

Related

magento2 mysql update table query

If someone can help with this MySQL query that would be great
I want to update this table
UPDATE catalog_product_entity_int
This query brings an array of values and works.
select catalog_product_entity.sku,catalog_product_relation.parent_id,catalog_product_flat_1.special_price
from catalog_product_entity
left join catalog_product_relation on (catalog_product_entity.entity_id = catalog_product_relation.parent_id)
left join catalog_product_flat_1 on (catalog_product_flat_1.entity_id = catalog_product_relation.child_id)
where catalog_product_entity.type_id = "configurable"
and catalog_product_flat_1.special_price > 1
GROUP BY catalog_product_relation.parent_id;
This is what I want to set based on the above query
SET catalog_product_entity_int.value = 1
where catalog_product_entity_int.attribute_id ='579'
and catalog_product_relation.parent_id = catalog_product_entity_int.entity_id
I'm not sure if I need to get the select query into a temp table first and if so how?
Theeasiest way is to join both table
i added aliases for he table to make it more readable
UPDATE catalog_product_entity_int t1,(select catalog_product_entity.sku,catalog_product_relation.parent_id,catalog_product_flat_1.special_price
from catalog_product_entity
left join catalog_product_relation on (catalog_product_entity.entity_id = catalog_product_relation.parent_id)
left join catalog_product_flat_1 on (catalog_product_flat_1.entity_id = catalog_product_relation.child_id)
where catalog_product_entity.type_id = "configurable"
and catalog_product_flat_1.special_price > 1
GROUP BY catalog_product_relation.parent_id) t2
SET t1.value = 1
where t1.attribute_id ='579'
and t2.parent_id = t1.entity_id
catalog_product_entity.sku and catalog_product_flat_1.special_price aren't used in the update and so you should check if they are needed
Try the select query
SELECT t1.value, t1.entity_id
FROM
catalog_product_entity_int t1 INNER JOIN (select catalog_product_entity.sku,catalog_product_relation.parent_id,catalog_product_flat_1.special_price
from catalog_product_entity
left join catalog_product_relation on (catalog_product_entity.entity_id = catalog_product_relation.parent_id)
left join catalog_product_flat_1 on (catalog_product_flat_1.entity_id = catalog_product_relation.child_id)
where catalog_product_entity.type_id = "configurable"
and catalog_product_flat_1.special_price > 1
GROUP BY catalog_product_relation.parent_id) t2
ON t2.parent_id = t1.entity_id
where t1.attribute_id ='579'
Thank you for the help. In the end this is what i did to make it work.
First create a temp table to store the values of the query
CREATE TABLE on_sale_updating AS
select catalog_product_entity.sku,catalog_product_relation.parent_id,catalog_product_flat_1.special_price
from catalog_product_entity
left join catalog_product_relation on (catalog_product_entity.entity_id = catalog_product_relation.parent_id)
left join catalog_product_flat_1 on (catalog_product_flat_1.entity_id = catalog_product_relation.child_id)
where catalog_product_entity.type_id = "configurable"
and catalog_product_flat_1.special_price > 1
and catalog_product_flat_1.special_to_date IS NULL OR catalog_product_flat_1.special_to_date >= CURDATE()
GROUP BY catalog_product_relation.parent_id;
Then run an update query against the temp table
update catalog_product_entity_int
inner join on_sale_updating ON catalog_product_entity_int.entity_id = on_sale_updating.parent_id
SET catalog_product_entity_int.value = 1
where catalog_product_entity_int.attribute_id ='579'
Once run for the first time add
DROP TABLE on_sale_updating;
to the first part.

Why does this SQL join work in 1 order but not the other?

I have 2 SQL joins here, one returns good results, the other returns 0 result set. Why is this? They are very similar except for join/column/table order. (By the way I'm using MySQL here)
Working Join (returns over 240,000 rows of good data)
SELECT
t1.email AS "email",
t1.record_id AS "record_id",
t2.status AS "status",
t3.item_record_id AS "item_record_id",
t1.ordered_at AS "started_at"
FROM `rs_orders` t1
INNER JOIN `cb_all_transactions` t2
ON t1.record_id = CONCAT('cb_sl_', t2.receipt)
INNER JOIN `rs_order_items` t3
ON t1.record_id = t3.order_record_id
WHERE t2.recurring = 'true'
ORDER BY t1.ordered_at ASC
NON Working Join (returns 0 rows)
SELECT
t1.email AS "email",
t1.record_id AS "record_id",
t1.ordered_at AS "started_at",
t2.item_record_id AS "item_record_id",
t3.status AS "status"
FROM rs_orders t1
INNER JOIN rs_order_items t2
ON t1.record_id = t2.order_record_id
INNER JOIN cb_all_transactions t3
ON t2.order_record_id = CONCAT('cb_sl_' + t3.receipt)
WHERE t3.recurring = 'true'
They're not the same. The second has CONCAT('cb_sl_' + t3.receipt). Replace + with ,.

Specific query optimization on MySQL

I have a table into MySQL DB (version 5.1.x), with the name table. Its columns are:
id, double_col_index1, double_col_index2, flag, col_index_1, a_date_col, col_index_2, col_index_3 with the following indexes:
a single index on double_col_index1 and double_col_index2
an index on col_index_1
an index on col_index_2
an index on col_index_3
Now, I have the following query:
UPDATE `table` t1 INNER JOIN
(SELECT t2.id FROM `table` t2
WHERE t2.double_col_index1 = 'fake_value1'
AND t2.double_col_index2 = 'fake_value2'
AND flag = 'true'
AND (col_index_1 = '' OR a_date_col < '1920-11-10 00:00:00')
AND
(SELECT count(t3.id) FROM `table` t3
WHERE t3.double_col_index1 = 'fake_value1'
AND t3.double_col_index2 = 'fake_value2'
AND t3.col_index_2 = t2.col_index_2
AND t3.col_index_3 = 'fake_col_index_3_1') > 0
AND
(SELECT count(t4.id) FROM `table` t4
WHERE t4.double_col_index1 = 'fake_value1'
AND t4.double_col_index2 = 'fake_value2'
AND t4.col_index_2 = t2.col_index_2
AND t4.col_index_3 = 'fake_col_index_3_2') > 0) tbl
ON t1.id = tbl.id SET col_index_1 = 'fake_value';
Question: I would need to improve this query, to give a better performance if possible. Would anyone have any suggestions on this?
One idea would be to use instead of INNER JOIN an t1.id in (.... What is your advice on this?
Basic idea of the join would be to do it as follows.
UPDATE `table` t1
INNER JOIN
(
SELECT t2.id
FROM `table` t2
INNER JOIN
(
SELECT DISTINCT col_index_2
FROM `table`
WHERE double_col_index1 = 'fake_value1'
AND double_col_index2 = 'fake_value2'
AND col_index_3 = 'fake_col_index_3_1'
) t3
ON t3.col_index_2 = t2.col_index_2
INNER JOIN
(
SELECT DISTINCT col_index_2
FROM `table`
WHERE double_col_index1 = 'fake_value1'
AND double_col_index2 = 'fake_value2'
AND col_index_3 = 'fake_col_index_3_2'
) t4
ON t4.col_index_2 = t2.col_index_2
WHERE t2.double_col_index1 = 'fake_value1'
AND t2.double_col_index2 = 'fake_value2'
AND flag = 'true'
AND (col_index_1 = '' OR a_date_col < '1920-11-10 00:00:00')
) tbl
ON t1.id = tbl.id
SET col_index_1 = 'fake_value';
This may be quite a bit quicker but will depend on many factors. MySQL will not use indexes for joining against the sub queries.
However there is a big issue with this (and your existing query) in MySQL
http://dev.mysql.com/doc/refman/5.7/en/update.html
Currently, you cannot update a table and select from the same table in a subquery.
There is a way round this, by doing a query on the sub query

MySQL - is a sub query what's needed here?

I currently have such a query:
SELECT
sec_to_time(avg(t1.sessiontime)) as aloc,
count(*) as calls
FROM
table1 AS t1
inner join
table2 as t2 ON t1.destination = t2.prefix
WHERE
t1.card_id = '101'
AND
t1.terminatecauseid = 1
group by t1.destination
Example result:
The 'calls' data is bound to 't1.terminatecauseid = 1' (meaning only answered calls)
I'd like to have a percentage of answered calles from the total calls made.
the same query without the condition (t1.terminatecauseid = 1) will give me the total calls made.
I'd like to know what is the best way to add another column called 'Average Success Rate' that will do:
total-calls*successful-calls/100
Is a subquery what's needed here? or a brand new and different query?
SELECT
sec_to_time(avg(t1.sessiontime)) as aloc,
sum(t1.terminatecauseid = 1) * 100 / count(*) as Average_Success_Rate,
sum(t1.terminatecauseid = 1) as calls
FROM
table1 AS t1
inner join
table2 as t2 ON t1.destination = t2.prefix
WHERE
t1.card_id = '101'
group by t1.destination

Mysql update using values from select

I have two queries. The first will return multiple rows:
SELECT parent_entry_id,child_entry_id FROM exp_playa_relationships WHERE parent_field_id = '34';
...And I would like to use the values (parent_entry_id,child_entry_id) and incorporate them into this query, replacing 'x' and 'y', and do it for each row returned by the first query.
UPDATE exp_channel_data AS t1,
(
SELECT field_id_46,field_id_47 FROM exp_channel_data WHERE entry_id = 'x') AS t2
SET t1.field_id_60 = t2.field_id_46, t1.field_id_61 = t2.field_id_47
WHERE t1.entry_id = 'y';
I think I need to use another JOIN, but I can't figure out how to implement one in my example. Any help would be much appreciated.
I think this is what you're after:
UPDATE exp_playa_relationships AS t0
JOIN exp_channel_data AS t1
ON t1.entry_id = t0.child_entry_id
JOIN exp_channel_data AS t2
ON t2.entry_id = t0.parent_entry_id
SET t1.field_id_60 = t2.field_id_46
, t1.field_id_61 = t2.field_id_47
Try this query
UPDATE exp_channel_data a1 INNER JOIN exp_playa_relationships a ON a1.entry_id = a.child_entry_id
INNER JOIN exp_channel_data b ON a.parent_entry_id = b.entri_id
SET a1.field_id_60 = b.field_id_46, ta1.field_id_61 = b.field_id_47
WHERE parent_field_id = '34'
Thanks all for your replies. The working syntax is:
UPDATE exp_channel_data AS t1,
(
SELECT
entry_id as ei2, child_entry_id, parent_entry_id, field_id_46 as f46,field_id_47 as f47
FROM
exp_channel_data JOIN exp_playa_relationships ON entry_id=child_entry_id AND parent_field_id = 34) AS t2
SET t1.field_id_60 = f46, t1.field_id_61 = f47
WHERE t1.entry_id=parent_entry_id;
Or in a more classic syntax, you need to adjust to your own foo & bar attributes, but use something like the following:
update exp_channel_data t1
set (t1.field_id_60,t1.field_id_61) = (
select t2.field_id_46 , t2.field_id_47
from exp_channel_data t2
where 1=1
and t2.entry_id = 'x'
and /* ENTER YOUR t1-t2 join condition here */
)
where 1=1
and t1.entry_id = y
;
But since you are MySQL I don't believe it supports compound subquery. As such:
update exp_channel_data t1
set t1.field_id_60 = (
select t2.field_id_46
from exp_channel_data t2
where 1=1
and t2.entry_id = 'x'
and /* ENTER YOUR t1-t2 join condition here */
) , t1.field_id_61 = (
select t3.field_id_47
from exp_channel_data t3
where 1=1
and t3.entry_id = 'x'
and /* ENTER YOUR t1-t3 join condition here */
)
where 1=1
and t1.entry_id = y
;