update from another table but join on calculated column - mysql

Table A has three columns; an IP address(varchar), lab ID(int), and origin (int).
Table B has two columns; an ID(int) and labName(varchar)
The labName is table B is made up of the IP address' first octet in A. For instance if the IP was 192.168.5.18 then there would be a lab name 'lab 192'. What I need to do is update Table A's labID column with the matching ID in table B.
I already have parsing done to build the lab name from the IP:
What I'm not sure how to do is the update based on that calculated field. Code below won't work but I'm hoping it might explain what I'm attempting to do:
UPDATE tableA
SET labID = (
SELECT labName
FROM tableB
WHERE labName = concat(β€˜lab β€˜, substring_index(ip, β€œ.”, 1)
)
WHERE origin = 3

MySQL will permit you to call a function (or any expression) in a join's ON clause using a join for the table_reference in UPDATE syntax
UPDATE
tableA
-- Join on the IP substring expression
INNER JOIN tableB ON tableB.labName = CONCAT('lab ', substring_index(tableA.ip, '.', 1))
-- Set labID to tableB ID
SET tableA.labID = tableB.ID
WHERE origin = 3

Related

fetch id from table1 based on some conditions and check if that id exists in other table

I have 2 tables; alternate identifier table and a master table
the above image represents the column from alternate identifiers table
and master table have these columns
Now, First I fetch company_group_id from alternate identifier table where bank_entity_id='somevalue' and id_value = 'somevalue';
if this query return nothing than end. if this query return company_group_id than I will check that company_group_id in master table where company_group_id = selected company group id.
after getting this if its present in the table than i will check hashcode if it presents in the master table.
separate queries are like this:
select company_group_id from aes_batch.aes_company_group_alternate_identifiers
WHERE ID_VALUE = '525' and BANK_ENTITY_ID='UOBS';
select company_group_id, hashcode from aes_batch.aes_company_group_master where company_group_id = 'value from the last query' and hashcode="value";
I want to combine these queries to get same result.
this is what I tried but failed.
SELECT t1.company_group_id
FROM aes_batch.aes_company_group_alternate_identifiers t1
LEFT JOIN aes_batch.aes_company_group_master t2
ON t1.company_group_id = t2.company_group_id
WHERE t2.company_group_id IS NULL;
SELECT *
FROM aes_batch.aes_company_group_master B
WHERE NOT EXISTS (SELECT 1
FROM aes_batch.aes_company_group_alternate_identifiers A
WHERE B.company_group_id = A.company_group_id);
Select a.company_group_id, b.company_group_id,
b.hashcode, a.id_value
from aes_batch.aes_company_group_alternate_identifiers a
LEFT JOIN aes_batch.aes_company_group_master b
ON b.company_group_id = a.company_group_id
WHERE a.id_value in ('524','525')
and a.bank_entity_id='UOBS';
can someone help me in this?

select records with multi key list

hi I have a list of primary keys of other tables in my field k in table A like this :
id=1 and ref=2 and fun=1
id=1 and ref=5 and fun=2
id=2 and ref=1 and fun=1
and I have a table B which it's primary key is id,ref,fun
now I want to select all records from table B where primary key matches the values in table A
,
of course the
select * from B where A.k
.. works
but get one record by one select
I ask for select all records from table B that matches A.k in table A.
thank you in advance.
MySQL will not treat the value of A.k as an expression to re-evaluate -- it's not substituted into the SQL and executed recursively. When you write WHERE A.k, it simply tests whether the contents of the k column is true or false.
You shouldn't put all the values in a single column. You should have separate columns for id, ref, and fun in table A. Then you can join the tables:
SELECT B.*
FROM B
JOIN A ON B.id = A.id AND B.ref = A.ref AND B.fun = A.fun
If you really want to have SQL expressions in a table column, you'll need to create dynamic SQL in a stored procedure.
SET #where = (SELECT GROUP_CONCAT(CONCAT('(', k, ')') SEPARATOR ' OR ')
FROM A);
PREPARE stmt FROM CONCAT('SELECT * FROM B WHERE ', #where);
EXECUTE stmt;
See the MySQL documentation on Prepared Statements

selecting values from a reference table

I have a users table and have roles such as admin|manager|employee which are represented in reference table called reference.
user table - id|first_name|last_name|type|status
reference table - id|table|type|key|value
Now the reference table contains integer key that match values so user.type has 0-admin,1-manager,2-employee which looks something like this
table:user
type:type
key:0
value:admin
My problem is when I have to values in a table which need to access the reference table.
table:user
type:status
key:0
value:enabled
Question: How can I access two reference table values in one statement?
//STATEMENT
SELECT a.id,a.first_name,a.last_name,b.value as user_type,b.value as user_status
FROM user AS a
JOIN reference as b
ON 'user'=b.table AND 'type'=b.type AND a.type = b.value AND a.status = b.value
You can join to the reference table twice (or three times, or four times...). Just give it two different aliases:
SELECT a.id,a.first_name,a.last_name,b.value as user_type,b.value AS user_type, b2.value as user_status
FROM user AS a
JOIN reference AS b
ON 'user'=b.table AND 'type'=b.type AND a.type = b.value
JOIN reference AS b2
ON 'user'=b2.table AND 'status'=b2.type AND a.status = b2.value
Unless I'm mis-interpreting your requirements, I believe the above is what you are seeking.

MySQL update column value with max value from another column

I have a database with 2 tables:
"services" and "service_performance"
Those 2 tables have a SERVICE_ID column.
In "services" the SERVICE_ID values are unique (each service has a single ID/entry).
In "service_performance" there is an AVERAGE_MEMORY column with multiple entries per service_id
I am trying to update the MAX_VALUE column in "services" table with the highest AVERAGE_MEMORY value taken from the "service_performance" table.
I know my query is wrong because it throws an error:
1054 - Unknown column 'service_performance.SERVICE_ID' in 'where clause'
While 'service_performance.SERVICE_ID' does exist.
Here is my query:
update _services
set MAX_VALUE = (SELECT MAX(AVERAGE_MEMORY) AS SERVICE_ID FROM service_performance)
where exists
(select *
from services
where `services`.`SERVICE_ID` = `service_performance`.`SERVICE_ID`);
You should find that this version works in MySQL:
update services s join
(select service_id, MAX(AVERAGE_MEMORY) as maxmem
from service_performance
group by service_id
) sp
on s.service_id = sp.service_id
set s.MAX_VALUE = sp.maxmem;
Your version would work if it had the right table name in the where clauses:
update services
set MAX_VALUE = (SELECT MAX(AVERAGE_MEMORY) AS SERVICE_ID
FROM service_performance
WHERE `services`.`SERVICE_ID` = `service_performance`.`SERVICE_ID`)
where exists (select *
from service_performance
where `services`.`SERVICE_ID` = `service_performance`.`SERVICE_ID`
);
I am assuming that update _services is a typo and should really be update services.
MySQL is complaining because in this query there is no service_performance table
Try it like this:
UPDATE _services s INNER JOIN service_performance p
ON s.SERVICE_ID=p.SERVICE_ID
SET s.MAX_VALUE=MAX(p.AVERAGE_MEMORY) GROUP BY p.SERVICE_ID
I don't have a database to test on, but firstly you haven't given the subquery an alias, so it doesn't know what service_performance.Service_ID is.
Secondly, in this context the subquery needs to return a single value rather than a table, so you may not be able to reference it. If adding the alias to the subquery doesn't work, then something like the following should work:
update _services
set MAX_VALUE = (SELECT MAX(AVERAGE_MEMORY) AS SERVICE_ID FROM service_performance
INNER JOIN
services
on services.SERVICE_ID = service_performance.SERVICE_ID)

sql query for deleting rows with NOT IN using 2 columns

I have a table with a composite key composed of 2 columns, say Name and ID. I have some service that gets me the keys (name, id combination) of the rows to keep, the rest i need to delete. If it was with only 1 row , I could use
delete from table_name where name not in (list_of_valid_names)
but how do I make the query so that I can say something like
name not in (valid_names) and id not in(valid_ids)
// this wont work since they separately dont identity a unique record or will it?
Use mysql's special "multiple value" in syntax:
delete from table_name
where (name, id) not in (select name, id from some_table where some_condition);
If your list is a literal list, you can still use this approach:
delete from table_name
where (name, id) not in (select 'john', 1 union select 'sally', 2);
Actually, no I retract my comment about needing special juice or being stuck with (AND OR'ing all your options).
Since you have a list of values of what you want to retain, dump that into a temporary table. Then do a delete against the base table for what does not exist in the temporary table (left outer join). I suck at mysql syntax or I'd cobble together your query. Psuedocode is approximate
DELETE
B
FROM
BASE B
LEFT OUTER JOIN
#RETAIN R
ON R.key1 = B.key1
AND R.key2 = B.key
WHERE
R.key1 IS NULL
The NOT EXISTS version:
DELETE
b
FROM
BaseTable b
WHERE
NOT EXISTS
( SELECT
*
FROM
RetainTable r
WHERE
(r.key1, r.key2) = (b.key1, b.key2)
)