How do I update a table in MySQL in the 1and1 domain? - mysql

I have a master table called client names. The key field is clientid and is a char 36. I have an address table. I need to update the address table's clientid fied, define the same as above, with the value from clientnames. My SQL runs but no rows are update. My first SQL is:
UPDATE address
SET clientid =
(
SELECT c.clientid FROM clientnames c
JOINrempAddress ra ON c.lastname = ra.lastname AND c.firstname = ra.firstname
)
The inner select returns the values I expect.
I have even tried:
UPDATE address SET clientid = 'AB3'.
Still no rows are updated. What am I doing wrong? Is 1and1 MySQL different and thus has different syntax?
Thank you.

My issue was that there were trailing spaces in the first name on one of the tables. When I used the TRIM function it worked as expected.

Related

How to use variables column name in where clause MySQL?

In this query:
SELECT *
FROM general_settings AS general_settings
JOIN settings_attribute AS settings_attribute ON settings_attribute.id = general_settings.settings_attribute_id
JOIN user_settings AS user_settings ON general_settings.user_settings_id = user_settings.id
WHERE
(settings_attribute.name = 'AAA' AND brand_settings.AAA <> general_settings.value)
OR
(settings_attribute.name = 'BBB' AND brand_settings.BBB <> general_settings.value)
OR
(settings_attribute.name = 'CCC' AND brand_settings.CCC <> general_settings.value)
;
I want a way using MySQL or Redshift to use settings_attribute.name as column name to avoid writing all the attribute names as a static in the query,
for example like this:
SELECT *
FROM general_settings AS general_settings
JOIN settings_attribute AS settings_attribute ON settings_attribute.id = general_settings.settings_attribute_id
JOIN user_settings AS user_settings ON general_settings.user_settings_id = user_settings.id
WHERE
brand_settings.#settings_attribute.name <> general_settings.value
;
No, this is not possible. In SQL, all identifiers (e.g. column names) must be explicit and fixed in the query at the time it is parsed, so the SQL engine can verify that the columns actually exist before it begins executing. It's not possible for a query to name different columns based on the string values it reads during execution.
What would happen if your settings_attribute.name contained 'XYZ' in some row, but there was no column by that name? It would be an error if you named a column that didn't exist, but in SQL that is checked at the time the query is parsed.

MySQL if result null change query

what if I have two strings: "123" and "abc". I want to select username if there's username "123" then choose it, if not found (null) then select username where "abc"
I have a table called USERS, this table responsibility with workflow engine account. I want to show columns in USERS:
username
email
usr_firstname
usr_lastname
I am using concat to merge column 3 and 4 with space between it. In the office, there are 2 types of employee:
origin/internal employee
outsource/partner employee
Origin employee login into every system using LDAP (FirstName.LastName), but outsource or partner employee login individually just for our workflow engine using employee identity number.
In this case, if I use something like:
Where username = 'employeenumber' or username = 'LDAPacc' the result is both account (used and unused for outsource) they appear. I want to show just 1 rows and 1 query but it's work with internal or even outsource (they will got data correctly for outsource).
You can use like this query;
SELECT *
FROM TABLE
WHERE username IN ('123', 'abc')
AND (username='123' OR NOT EXISTS(SELECT * FROM TABLE WHERE username='abc'))
You could use COALESCE.
COALESCE selects the first non null value out of the ones supplied.
So you could use....
SELECT COALESCE(String_123, string_ABC);
If string_123 has a value it will select that, otherwise it will select string_ABC unless of course they are both null.
So to be safe include a default value.......
SELECT COALESCE(String_123, string_ABC, string_Default);
I've found when I tested my logic to mysql tryit editor by w3schools and It's worked properly what I need. Here's my query:
SELECT * FROM Customers WHERE CustomerID = 'zz' OR (NOT EXISTS (SELECT * FROM Customers WHERE CustomerID = 'zz') AND CustomerID = '3')
let's say CustomerID is equivalent to my username column, then I tried to swap 'zz' and '3' value and it's still works. I hope there's more simple query than this

cross table update can't work

I tried many code (some from stackoverflow), none of them can work.
Here is the structure of my mysql database:
table hesk_tickets : id, name, email
table hesk_callers : empnum, email, dept
the name column in hesk_tickets references the employee number, as does the empnum in hesk_callers
At beginning there is no other employee info in hesk_tickets but name. I want to add more employee info into it to make it easy to callback.
Then I import an xls file containing employee info into a new table named hesk_calles. I want to update hesk_tickets columns like email on lines that match the employee number in hesk_callers.
I tried this:
UPDATE hesk_tickets t1, hesk_callers t2
SET t1.email = t2.email
WHERE t1.name = t2.empnum;
also tried
UPDATE hesk_tickets ht
JOIN hesk_callers hc ON ht.name = hc.empnum
SET ht.email = hc.email
0 row(s) affected.
there are 6000 records in hesk_tickets and 1000 records in hesk_callers.
any solution will be appreciated,thx.
Try executing
select count(*) from hesk_tickets ht join hesk_callers hc on ht.name = hc.empum
to verify you actually have some matching data to update. You'll probably find that query returns zero. If that returns a number greater than zero, then it means that your UPDATE query is affecting zero rows because the email addresses already match (and therefore don't need updating)

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
)

Update query on linked MySQL table from SQL Server

I have a MS SQL Server with a linked MySQL server. I need to partially synchronize a table between the two servers. This is done in three steps and based on a condition:
Delete all rows from the MySQL table that do not satisfy the condition
Insert all new rows in the MySQL table that satisfy the condition
Update all rows in the MySQL server that satisfy the condition and have different data between MySQL and SQL Server
Steps 1 and 2 always run without a problem. But step 3 won't run if there is anything to update. The query fails with the following exception: The rowset was using optimistic concurrency and the value of a column has been changed after the containing row was last fetched or resynchronized.].
This is the query that is executed:
update mysqlserver...subscribers
set Firstname = Voornaam,
Middlename = Tussenvoegsel,
Surname = Achternaam,
email = e-mail
from mysqlserver...subscribers as b, tblkandidaat
where (b.kandidaatid = tblkandidaat.kandidaatid) and
(tblkandidaat.kandidaatid in (
select subsc.kandidaatid
from mysqlserver...subscribers subsc inner join tblKandidaat
on (subsc.kandidaatid=tblKandidaat.kandidaatid)
where (subsc.list=1) and
((subsc.firstname COLLATE Latin1_General_CI_AI <> Voornaam
or (subsc.middlename COLLATE Latin1_General_CI_AI <> Tussenvoegsel)
or (subsc.surname COLLATE Latin1_General_CI_AI <> tblKandidaat.Achternaam)
or (subsc.email COLLATE Latin1_General_CI_AI <> tblKandidaat.e-mail))
));
Anybody has an idea about how to prevent this?
Try this query instead:
update b
set
Firstname = Voornaam,
Middlename = Tussenvoegsel,
Surname = Achternaam,
email = e-mail
from
mysqlserver...subscribers b
inner join tblkandidaat k on b.kandidaatid = k.kandidaatid
where
b.list=1
and (
b.firstname COLLATE Latin1_General_CI_AI <> k.Voornaam
or b.middlename COLLATE Latin1_General_CI_AI <> k.Tussenvoegsel
or b.surname COLLATE Latin1_General_CI_AI <> k.Achternaam
or b.email COLLATE Latin1_General_CI_AI <> k.e-mail
)
It's best practice to use ANSI joins and properly separate JOIN conditions from WHERE conditions.
It's more readable to use aliases for all your tables instead of long table names throughout the query.
It's best to use the aliases for all column references instead of leaving them blank. Not only is it a good habit and makes things clearer, it can avoid some very nasty errors in inner-vs-outer table references.
If performance is also an issue: linked server joins sometimes devolve to row-by-row processing in the DB data provider engine. I have found cases where breaking out part of a complex join across a linked server into a regular join followed by a cross apply hugely reduced the unneeded rows being fetched and greatly improved performance. (This was essentially doing a bookmark lookup, aka a nonclustered index scan followed by clustered index seek using those values). While this may not perfectly mesh with how MySql works, it's worth experimenting with. If you can do any kind of trace to see the actual queries being performed on the MySql side you might get insight as to other methods to use for increased performance.
Another performance-improving idea is to copy the remote data locally to a temp table, and add an ActionRequired column. Then update the temp table so it looks like it should, putting 'U', 'I', or 'D' in ActionRequired, then perform the merge/upsert across the linked server with a simple equijoins on the primary key, using ActionRequired. Careful attention to possible race conditions where the remote database could be updated during processing are in order.
Beware of nulls... are all those columns you're comparing non-nullable?
You might try creating a second table in mysql, doing an insert from sql-server into that empty table for all changed lines and doing Step 3 between the two mysql tables.
try to not using sub-query in your where statement. Sub-query may return more than one row, and then you got the error.
try creating a view which has source, destination and has_changed column between and has linked tables joined. then you can issue query
update vi_upd_linkedtable set destination=source where has_changed=1
This is a shot in the dark, but try adding FOR UPDATE or LOCK IN SHARE MODE to the end of your subselect query. This will tell MySQL that you are trying to select stuff for an update within your transaction and should create a row level write lock during the select rather than during the update.
From 13.2.8.3. SELECT ... FOR UPDATE and SELECT ... LOCK IN SHARE MODE Locking Reads:
SELECT ... LOCK IN SHARE MODE sets a
shared mode lock on the rows read. A
shared mode lock enables other
sessions to read the rows but not to
modify them. The rows read are the
latest available, so if they belong to
another transaction that has not yet
committed, the read blocks until that
transaction ends.
For rows where the names are the same, the update is a no-op.
You don't save any work by trying to filter out the rows where they're the same, because the data still has to be compared across the link. So I can't see any benefit to the subquery.
Therefore the query can be simplified a lot:
update mysqlserver...subscribers
set Firstname = Voornaam,
Middlename = Tussenvoegsel,
Surname = Achternaam,
email = e-mail
from mysqlserver...subscribers as b join tblkandidaat
on b.kandidaatid = tblkandidaat.kandidaatid;
where b.list = 1;
Eliminating the subquery might make your the locking issue go away. MySQL does have some issues combining a select and an update on the same table in a given query.
Try this. I wrote several of these today.
update b
set
Firstname = Voornaam,
Middlename = Tussenvoegsel,
Surname = Achternaam,
email = e-mail
from
mysqlserver...subscribers b
inner join tblkandidaat k on b.kandidaatid = k.kandidaatid
where
b.list=1
and (
ISNULL(b.firstname,'') COLLATE Latin1_General_CI_AI <> ISNULL(k.Voornaam,'')
or ISNULL(b.middlename,'') COLLATE Latin1_General_CI_AI <> ISNULL(k.Tussenvoegsel,'')
or ISNULL(b.surname,'') COLLATE Latin1_General_CI_AI <> ISNULL(k.Achternaam,'')
or ISNULL(b.email,'') COLLATE Latin1_General_CI_AI <> ISNULL(k.e-mail,'')
)
Using the ISNULL allows you to null your columns.