Stymied building this cross-database query - mysql

I'm trying to migrate some data from an old database to a new one with a slightly different schema and my SQL isn't terribly strong.
Old schema: There is a table we'll call "Person" with a field which can have set of permutations of 3 flags. The Person table has a foreign key to another table we'll call "Flags". They Flags table has rows for each of these flag combinations in a String:
1 - Yes No No
2 - Yes Yes No
3 - Yes No Yes
4 - Yes Yes Yes
5 - No Yes No
6 - No Yes Yes
7 - No No Yes
The new schema doesn't require this table (thankfully). These flags are simply fields in the "Person" table now as BIT fields.
What I want to do is something like a:
UPDATE database2.Person SET (flag1, flag2, flag3) VALUES (true, false false) WHERE database1.Person.flag_id = 1;
I could then run 7 different queries changing the IDs and the values accordingly. The problem, of course, is that the above isn't correct SQL. I think I need some kind of JOIN ...or a subselect in the where clause or something?
Stumped on the best way forward. My parting thought here is that this doesn't need to be compressed into a single query, or particularly elegant. I expect to run this query once and be done with it.

You could try something like:
update database2.Person p2 join database1.Person p1 on p1.PersonId = p2.PersonId
set flag1 = case when p1.Flag_id in (1,2,3,4) then true else false end case,
flag2 = case when p1.Flag_id in (2,4,5,6) then true else false end case,
flag3 = case when p1.Flag_id in (3,4,6,7) then true else false end case
(edited for mySQl syntax)

This should work if I'm understanding your question. It assumes you have a Person_Id matching in each table.
UPDATE db2.Person p
JOIN db1.Person p2 ON p.Person_Id = p2.Person_Id
SET p.Flag1 = 1,
p.Flag2 = 0,
p.Flag3 = 0
WHERE p2.Flag_Id = 1;
If the flag values in the Flags table were columns, you could easily run a single query, but as I'm understanding it, it's just a string field. This is an example:
UPDATE db2.Person p
JOIN db1.Person p2 ON p.Person_Id = p2.Person_Id
JOIN db1.Flags f ON p2.Flag_Id = f.Flag_Id
SET p.Flag1 = CASE WHEN f.Flag1 = 'Yes' THEN 1 ELSE 0 END,
p.Flag2 = CASE WHEN f.Flag2 = 'Yes' THEN 1 ELSE 0 END,
p.Flag3 = CASE WHEN f.Flag3 = 'Yes' THEN 1 ELSE 0 END

Related

Multiple WHERE conditions using AND => No query result

I have a table with a few thousand entries. And My purpose is to select all entries from all versions that correspond to a given one. And the resulted entries must correspond exactly to the given entry.
But somehow, the SQL query does not work. The original project uses Access 2007. But I have tried also in MySQL and no success
I put here the sql query, but I also made a SQL fiddle:
SELECT
idvalue,
idtag,
iddevice,
idversion,
idtext,
description,
idaccess,
defaultvalue,
minimumvalue,
acceptedvalue,
maximumvalue,
outofrangevalue,
iddatatypepn,
iddatatypeopc,
size,
idresolution,
idunit,
idaccuracy,
enumerationvalues,
comments,
remanentvolatile,
storedatpn,
storedatmain,
`generated`,
edittime
FROM
SomeValues
WHERE
idtag = 2 AND iddevice = 1
AND idtext = 433
AND description = 'Input voltage (AC)'
AND idaccess = 12
AND defaultvalue IS NULL
AND minimumvalue =0
AND acceptedvalue = 5300
AND maximumvalue = 10050
AND outofrangevalue = 11000
AND iddatatypepn = 2
AND iddatatypeopc = 19
AND size = 2
AND idresolution = 2
AND idunit = 1
AND idaccuracy = 2
AND enumerationvalues IS NULL
AND comments IS NULL
AND remanentvolatile IS NULL
AND storedatpn = FALSE
AND storedatmain = FALSE
AND `generated` = TRUE
Fiddle: here
Can you please explain what is wrong with the sql query?
The result should be those 3 entries from the fiddle table.
And yes, I must use all the conditions from the "Where" clause, since the entries can match 90% but also have small differences
You have problem in line:
AND description = 'Input voltage (AC)'
change it to:
AND description = '"Input voltage (AC)"'
and everything will works.
Problem lies in the fact that you searched for text Input voltage (AC) instead of "Input voltage (AC)" (how is stated in column description).

Update database record by selected id and reset the initial record

Please how do i update all record to 0 and set only the selected ID to 1
UPDATE address SET default_addr = 1
WHERE addr_id = 100 AND user = 'peter'
The above query will update the selected address to 1 which is good, but i want to set other address or the old selected default to 0 with one query
In MySQL, you can do:
UPDATE address
SET default_addr = (addr_id = 100 AND user = 'peter');
(This shorthand uses the fact that MySQL treats booleans as numbers in a numeric context, with "0" for false and "1" for true.)
If you want only one default address for the user named Peter, then use a where:
UPDATE address
SET default_addr = (addr_id = 100)
WHERE user = 'peter';
I suspect this is the logic that you really want.
use a conditional update using case statement
update address set default_address = case when addr_id = 100 and user = 'peter' then 1 else 0 end
here is a functional example
I built a sample schema. These are often helpful to provide in your future questions.

MySQl query to UPDATE if Data is Null or Empty with a CASE Statement

Iam struck up with a query. When i edit a data in Table A, it needs to check if the same data is present in Table B, If data is present in Table B, just ignore updation, if data is empty or Null, then the data from Table A needs to Update in Table B. With the following query iam almost achieving it but the issue is When the Data is present in Table B, its just deleting the data. It should actually ignore it when data is present. A small issue with the case statement i guess. Pls help me on this.
$strSQLInsert2 = "UPDATE Table B
SET
`tender_intendername` = CASE WHEN `tender_intendername`='' or `tender_intendername` IS NULL
THEN '".$values["intendername1"]."' END,
`no_of_participants` = CASE WHEN `no_of_participants`='' Or `no_of_participants` IS NULL
THEN '".$values["no_of_participants"]."' END
WHERE tender_id=" . $values["tender_id"];
You have to add an ELSE to the CASE expression:
UPDATE Table B
SET `tender_intendername` = CASE
WHEN `tender_intendername`='' or
`tender_intendername` IS NULL
THEN '".$values["intendername1"]."'
ELSE `tender_intendername` END,
`no_of_participants` = CASE
WHEN `no_of_participants`='' Or
`no_of_participants` IS NULL
THEN '".$values["no_of_participants"]."'
ELSE `no_of_participants` END
WHERE tender_id=" . $values["tender_id"];
The ELSE statement sets each field equal to itself, hence it guarantees that the field will not change when the field is not empty and not NULL.
I solved it. But need to write two queries to achieve the result.
$strSQLInsert2 = "UPDATE `TableB`
SET
`tender_intendername` = '".$values["intendername1"]."'
WHERE
`tender_intendername` = ''
OR `tender_intendername` IS NULL AND tender_id=" . $values["tender_id"];

Update Same mysql field twice in single query

I am not sure if its possible or not, Just want to know if it is. I have column plan_popular which has default value 0. Lets same i have a list :
Plan Name | plan_popular | amount
===================================
plan A 0 25.00
plan B 1 50.00
plan C 0 90.00
This is how i am doing:
$stmt = "update {CI}plans set plan_popular = 0";
$this->db->query($stmt);
$stmt2 = "update {CI}plans set plan_popular = 1 where plan_id = ?";
$this->db->query( $stmt2, array($plan_id) );
Now i have set the plan C to make. Now i want to reset it and want to make popular plan C to 1. What i am doing is running two queries, One i reset and make the plan_popular 0 and the second is get the update the plan C to 1 with there id. Is it possible in single query?
You can use an expression to determine the value to assign:
UPDATE {CI}plans
SET plan_popular = IF(plan_id = ?, 1, 0);
try this,
UPDATE {CI}plans
SET `plan_popular` = CASE `Plan Name`
WHEN 'plan C' THEN 1
ELSE 0
END
WHERE `Plan Name` IN((select `Plan Name` from {CI}plans where plan_popular=1 ) , 'plan C');
Updates can be expensive, what with manipulating locks, triggers and constraints firing, etc. In general, you want to avoid updating a field to the same value it already has. In English, if plan_id = variable and plan_popular is 0 then set it to 1 but if plan_id is any other value and plan_popular is 1 then set it to 0.
UPDATE {CI}Plans
SET plan_popular = if( plan_id = ?, 1, 0 )
where (plan_id = ? and plan_popular = 0)
or (plan_id <> ? and plan_popular = 1);
The where clause lets through only those rows that will actually be changed by the update. If this is a largish table, that can make quite a difference in response time. Logic is much less expensive than any actual operation that can performed in the database.

Update table using alias

I need to fill some fields in a table getting informations from other records of the same table.
I tried to write a query to explain what I want to do:
update globale2
set
nita = t.nita,
tita = t.tita,
notaita = t.notaita
where
neng = t.neng and
nita is null
(select nita, neng, tita, notaita from globale where uris='mma' and nita is not null) as t
edit to eplain better:
every records have these fields: "nita", "tita", "notaita", "neng" ("neng" cannot be null)
I want to fill these fields: "nita", "tita", "notaita" (where "nita" is empty)
with the same values from another record where "neng" equals the other "neng"
You can however, join the two tables.
UPDATE globale2 g
INNER JOIN globale gg
ON g.neng = gg.neng
SET g.nita = gg.nita,
g.tita = gg.tita,
g.notaita = gg.notaita
WHERE g.nita IS NULL
AND gg.uris = 'mma'
AND gg.nita IS NOT NULL
assume there is a table A_temp, with two columns 'one' and 'two'.
TABLE A_temp
ONE TWO
1 2
this is the present status of the table.
The query
UPDATE (SELECT * FROM A_temp ) A SET one = A.two where one = '1'
updates the table as
ONE TWO
2 2
Hope you get the idea and that it helps..