if else in mysql query - mysql

Let's say that I want to insert a record in a table. Each record has an ID (not unique)
I want to check two columns (let say first and last name) and if these columns have already been in my table use that id, unless use another id for the new record.
In other words, I want to say IF the name is new assign a new ID else assign the id of that record. (Don't worry about the new id, assume that I have an original id for each record)
For example let say I have the following records in my table:
FirstName | LastName | Location | Age ... | ID
John | Smith | Canada | 12 ... | 1234
John | Smith | US | 21 ... | 1234
And now I want to add another John Smith. So I want the same ID for the new record. While if I want to add Paul Smith, I want a new ID for that.

INSERT INTO YourTable (FirstName, LastName, Location, ID)
SELECT new.FirstName, new.LastName, new.Location, IFNULL(present.ID, new.ID)
FROM
(SELECT 'John' AS FirstName
, 'Smith' AS LastName
, 'UK' AS Location
, 1111 AS ID) AS new
LEFT OUTER JOIN YourTable AS present
ON present.FirstName = new.FirstName
AND present.LastName = new.LastName
ORDER BY present.ID DESC
LIMIT 1;
SQLFiddle

You can use IFNULL to get the current value or use a new one, when that one is missing.
INSERT INTO your_table (id, first_name, last_name, other_stuff) VALUES (
( SELECT IFNULL (
( SELECT id FROM your_table WHERE first_name = 'John' AND last_name = 'Doe'),
'new_id'
),
),
'John',
'Doe',
'Your other data'
)
Though it does sound to me that you are trying to assign a unique id for every first/last name combination. Depending on your use case there may be better ways to do that (if I am right) like, keep the id <-> name mapping in a separate table for example, and only use the id in the table that you are referring to in this post.

INSERT .... ON DUPLICATE KEY UPDATE
You can also specify a different action for duplicate keys to suit your needs.
I believe the fields you are checking against need to be indexed to work.
Hope that helps.

CASE WHEN EXISTS (SELECT * FROM `names` WHERE `first`=$first AND `last`=$last) THEN (SELECT MAX(`id`) FROM `names` WHERE `first`=$first AND `last`=$last) ELSE $new_id
...is the closest literal answer to your question. However, in your case, this might be better:
IFNULL(SELECT MAX(`id`) FROM `names` WHERE `first`=$first AND `last`=$last, $new_id)
CASE WHEN is an actual if-then-else structure, whereas IFNULL (or equivalently, COALESCE) just provides a default if nothing is found.

Related

Update values of one column with multiple values

There is a table and that table has a column with a name country and I need to change values at that column in one query instead of multiple queries.
In this query, I change any value with Egypt to be 1
UPDATE subscribers
SET country = 1 WHERE country = 'Egypt';
in this query, I change any value with Qatar to be 2
UPDATE subscribers
SET country = 2 WHERE country = 'Qatar';
Any help to make these two queries in one?
Consider:
UPDATE subscribers SET country =
CASE
WHEN country = "Egypt" THEN 1
WHEN country = "Qatar" THEN 2
ELSE country
END
;
Now imagine doing that expression for many more countries. Instead join to a table that 'maps' data association (a master table of country names). Join on CountryName fields and update destination table CountryName field with ID from 'mapping' table. Convert to number type field. Or play it safe and update to another field and when all looks good, delete the original field.
You can use a case expression in MySQL:
UPDATE subscribers
SET country = (CASE WHEN country = 'Egypt' THEN 1 ELSE 2 END)
WHERE country IN ('Egypt', 'Qatar');
However, I would recommend using a derived table:
UPDATE subscribers s JOIN
(SELECT 'Egypt' as country, '1' as new_country UNION ALL
SELECT 'Qatar' as country, '2' as new_country
) x
USING (country)
SET s.country = x.new_country;

How to update values for several columns in a Table with a single query?

I have a table something like below,
ID Name EMail Gender
and there are values already in this table.
Now, I used below query to add age.
alter table tblPerson add Age int
Now, my row structure looks like
ID Name EMail gender Age
Now, I have list of ages. Any query to add these ages into newly created column?
All the ages are sorted according to ID. So no IF logic required. I just need to add column data.
Thanks.
Store the values in a temporary table with the id. Then use a join:
update t join
idages ia
on t.id = io.id
set t.age = ia.age;
You can also do this with a giant case expression, but that is prone to error:
update t
set t.age = (case when id = id1 then age1
when id = id2 then age2
when id = id3 then age3
. . .
end)
where t.age in (id1, id2, id3, . . .);

Divide one column into multiple in a new table

I have a table set up like this
id (PK) | regID (FK) | fieldID | fieldValue
There are multiple fields that can be used to enter data and which are all stored in the fieldValue column. What I'd like to do is migrate this data over to a 2nd table that looks like
regID | Name | Occupation | etc | etc
Where the columns (other than regID) are associated with fieldIDs.
I first tried populating the new table with the unique regIDs and then tried to update the rest of the row information from there based on the matching regIDs and appropriate fieldIDs but I wasn't able to get far with that.
Then I tried something like
`INSERT INTO newData(regID, pName) VALUES
((SELECT distinct regID FROM fieldData),
(SELECT fieldValue FROM fieldData WHERE fieldID= 14 ORDER BY regID))`
which obviously didn't work. I'm still thinking that the first option may be the better way, but even then I don't think it's great. Any ideas how to get this data moved over to be more organized?
you need to use case based aggregation
Here is how you do it using insert into select and case based aggregation
INSERT INTO newData(regID, pName, occupation)
select regID,
max(case when filedid=14 then fieldDate end) as pName,
max(case when filedid=15 then fieldDate end) as occupation,
.....
from fieldData
group by regID

MySQL: Insert using results of Select field from pair clause

I've got a requirement to add an additional item of data to an existing row and insert the result in a second table. The data item is different for each row I am selecting, so I can't just add it to the SELECT statement. The original query is:
SELECT player_id,token_id,email FROM players
WHERE token_id in (101,102) OR email in ("test4#test.com");
I'd like to be able to do something like a Row Constructor and write the query something like this:
SELECT player_id,token_id, email, key_val FROM players
WHERE (token_id, key_val) in ( (101, 'xyz'),(102,'abc'))
OR (email, key_val) in ( ("test4#test.com", 'qpr') );
So that the second value ('key_val') from the pair in the IN clause would be added into the SELECT output as the last column. And then the whole lot will get inserted into the final table.
The number of items in the IN clause will vary from 3 to potentially 100's.
Really sorry if this is a dup. I've looked up things like:
Select Query by Pair of fields using an in clause
MySQL: How to bulk SELECT rows with multiple pairs in WHERE clause
I guess I could use a temporary table but I'm concerned about the number of times that this is going to be called.
Edit--
To clarify, the source table is something like:
player_id, token_id, email
===================================
1 101 null
2 102 null
3 null test4#test.com
and the date being supplied is:
(token_id=101, key_val='xyz'),(token_id=102, key_val='abc'),(email='test4#test.com', key_val='qpr')
and the intended output would be:
player_id token_id email keyy_val
========== ========= ============== ========
1 101 null zyz
2 102 null abc
3 null test4#test.com qpr
Hope this makes it clearer.
try this
SELECT player_id,token_id, email, key_val
FROM players
WHERE token_id in (101,102) AND key_val IN ('xyz','abc')
OR ( email in ("test4#test.com") AND key_val IN ('qpr') );
EDIT -.
try this
SELECT player_id,token_id, email, key_val
FROM ( select player_id,token_id, email,
if(`token_id` =101 , 'xyz',
if(`token_id` =102 , 'abc' ,
if(email = "test4#test.com" , 'qpr' , NULL))
) key_val
from players
)p
DEMO SQLFIDDLE

Insert multi column result into single column table

I have a table 'movies' with three Columns: 'id', 'master_id' and 'searchMe' (simplified). I have another Table 'temp_ids' with a single column: 'id'. It is a temporary table, but I don't think that matters.
When I make a query on my table 'movies' like
SELECT `id`, `master_id` FROM 'movies' WHERE searchMe = '1';
I get a multi column result. Now I want to insert every id and every master_id into the 'temp_ids'-Table, but one at a time. So if my result is
id_1 | master_1
id_2 | master_2
id_3 | NULL
I want my temp_ids to look like
id_1
master_1
id_2
master_2
id_3
So I want to convert every single column in the result into its own row. How can I do that in an elegant way?
I know I can do it in multiple queries, searching for id and master_id separatly, and I know I can solve that problem with PHP or so. But I would prefer it to solve that problem in a single mysql-query, if such a thing is possible.
I made a sqlfiddle for this:
http://sqlfiddle.com/#!2/b4a7f/2
To SELECT the data you can use a UNION ALL for this:
SELECT `id`
FROM movies
WHERE searchMe = 1
union all
SELECT `master_id`
FROM movies
WHERE searchMe = 1
and master_id is not null
see SQL Fiddle with Demo
Doing it this way, you cannot distinguish between what value comes from each column, so you can always add an indicator, this will give you two columns but then you know where the data came from:
SELECT `id`, 'id' type
FROM movies
WHERE searchMe = 1
union all
SELECT `master_id`, 'master'
FROM movies
WHERE searchMe = 1
and master_id is not null
Then you would just use this query to INSERT INTO temp using this SELECT
It would be like this
INSERT INTO temp_ids(id)
SELECT id
FROM
(
SELECT id
FROM FirstTable
UNION
SELECT master AS id
FROM SecondTable
) t