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
Related
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?
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
This question already has an answer here:
Select values from a list that are not in a table
(1 answer)
Closed 2 years ago.
I have a list of values:
('WEQ7EW', 'QWE7YB', 'FRERH4', 'FEY4B', .....)
and the dist table with a dist_name column.
and I need to create SQL query which would return values from the list which don't exist in the dist_name column.
Yo need to use left join. This requires creating a derived table with the values you care about. Here is typical syntax:
select v.val
from (values ('WEQ7EW'), ('QWE7YB'), ('FRERH4'), ('FEY4B')
) v(val) left join
t
on t.col = v.val
where t.col is null;
Not all databases support the values() table constructor but allow allow some method for creating a derived table. In MySQL, this looks like:
select v.val
from (select'WEQ7EW' as val union all
select 'QWE7YB' as val union all
select 'FRERH4' as val union all
select 'FEY4B' as val
) v(val) left join
t
on t.col = v.val
where t.col is null;
You would typically put this list of values in a derived table, and then use not exists. In MySQL:
select v.dist_name
from (
select 'WEQ7EW' as dist_name
union all select 'QWE7YB'
union all ...
) v
where not exists (select 1 from dist d where d.dist_name = v.dist_name)
Or if you are running a very recent version (8.0.19 or higher), you can use the VALUES ROW() syntax:
select v.dist_name
from (values row('WEQ7EW'), row('QWE7YB'), ...) v(dist_name)
where not exists (select 1 from dist d where d.dist_name = v.dist_name)
SELECT TRIM(TRAILING ',' FROM result) result
FROM ( SELECT #tmp:=REPLACE(#tmp, CONCAT(words.word, ','), '') result
FROM words, (SELECT #tmp:='WEQ7EW,QWE7YB,FRERH4,FEY4B,') arg
) perform
ORDER BY LENGTH(result) LIMIT 1;
fiddle
The list of values to be cleared from existing values is provided as CSV string with final comma and without spaces before/after commas ('WEQ7EW,QWE7YB,FRERH4,FEY4B,' in shown code).
If CSV contains duplicate values all of them will be removed whereas non-removed duplicates won't be compacted. The relative arrangement of the values will stay unchanged.
Remember that this query performs full table scan, so it is not applicable to huge tables because it will be slow.
I want to loop through some records and update them with an ad hoc query in MySql. I have a name field, so I just want to loop though all of them and append a counter to each name, so it will be name1, name2, name3. Most examples I see use stored procs, but I don't need a stored proc.
As a stepping stone on your way to developing an UPDATE statement, first generate a SELECT statement that generates the new name values to your liking. For example:
SELECT t.id
, t.name
, CONCAT(t.name,s.seq) AS new_name
FROM ( SELECT #i := #i + 1 AS seq
, m.id
FROM mytable m
JOIN (SELECT #i := 0) i
ORDER BY m.id
) s
JOIN mytable t
ON t.id = s.id
ORDER BY t.id
To unpack that a bit... the #i is a MySQL user variable. We use an inline view (aliased as i) to initialize #i to a value of 0. This inline view is joined to the table to be updated, and each row gets assigned an ascending integer value (aliased as seq) 1,2,3...
We also retrieve a primary (or unique) key value, so that we can match each of the rows from the inline view (one-to-one) to the table to be updated.
It's important that you understand how that statement is working, before you attempt writing an UPDATE statement following the same pattern.
We can now use that SELECT statement as an inline view in an UPDATE statement, for example:
UPDATE ( SELECT t.id
, t.name
, CONCAT(t.name,s.seq) AS new_name
FROM ( SELECT #i := #i + 1 AS seq
, m.id
FROM mytable m
JOIN (SELECT #i := 0) i
ORDER BY m.id
) s
JOIN mytable t
ON t.id = s.id
ORDER BY t.id
) r
JOIN mytable u
ON u.id = r.id
SET u.name = r.new_name
SQL Fiddle demonstration here:
http://sqlfiddle.com/#!2/a8796/1
I had to extrapolate, and provide a table name (mytable) and a column name for a primary key column (id).
In the SQL Fiddle, there's a second table, named prodtable which is identical to mytable. SQL Fiddle only allows SELECT in the query pane, so in order to demonstrate BOTH the SELECT and the UPDATE, I needed two identical tables.
CAVEAT: be VERY careful in using MySQL user variables. I typically use them only in SELECT statements, where the behavior is very consistent, with careful coding. With DML statements, it gets more dicey. The behavior may not be as consistent in DML, the "trick" is to use a SELECT statement as an inline view. MySQL (v5.1 and v5.5) will process the query for the inline view and materialize the resultset as a temporary MyISAM table.
I have successfully used this technique to assign values in an UPDATE statement. But (IMPORTANT NOTE) the MySQL documentation does NOT specify that this usage or MySQL user variables is supported, or guaranteed, or that this behavior will not change in a future release.
Have the names stored in a table. Do a join against the names and update in the second table you want to.
Thanks
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)
)