A table called test has columns :
person_id (Unique) & special_num
Table:
Outcome :
Would like to create a new column called div to determine which person got the special_num that is divisible by 10 and which person did not instead of true or false would like to have a yes or no.
I am new to MySQL and have never tried it but gave it a shot please tell me how to get this:
SELECT * FROM test WHERE special_num % 10 = 0 AS div from test;
I am unable to figure out how to input values and if it is the right way of doing it
If you want a column, then it goes in the select:
select t.*,
( (special_num % 10) = 0) as div
from t;
You need a CASE expression:
SELECT *,
CASE WHEN special_num % 10 = 0 THEN 'Yes' ELSE 'No' END AS `div`
FROM test
Here is my SQLFiddle to mimic this problem.
First step is to create a new column by ALTERing the table.
ALTER TABLE PERSONS
ADD is_special VARCHAR(3);
Now run an UPDATE query that checks if the special_num % 10 is zero or not, and if it is, then set is_special to yes.
UPDATE PERSONS SET is_special = CASE WHEN special_num % 10 = 0 THEN 'yes' ELSE 'no' END;
Having said that, it is a bad idea to store values that are derived or calculated from other fields. You may want to use this in a view, but not in a table.
Related
I am a beginner in MySQL and i want to do a check for values but within a range, i have this:
SELECT t1.width, COUNT( t1.width )
FROM test t1
INNER JOIN (
SELECT t2.width
FROM test t2
GROUP BY width
HAVING COUNT( t2.width ) >1
)t2 ON t1.width BETWEEN (t2.width +1000) AND (t2.width -1000)
ORDER BY t1.width
So what i want to do is to check if there is two values of 'width' with a difference of +1000 or -1000.
The result is always null.
could you please tell me what is wrong with the query?
I don't fully understand what your data is. The way I understand is you are looking to see if two values from two columns have a specific difference, i.e the first value in the first column is 2000 and the first value in the second column is 1000, since there is a difference of 1000 you want this noted. You could use the CASE function (more detail here https://www.w3schools.com/sql/func_mysql_case.asp).
Say you have one column called width_1 which consists of different values of widths, and a second column called width_2 which also consists of different width values, all contain in a table called width_table, you could use the following:
SELECT
CASE
WHEN width_1 - width_2 = 1000 OR width_1 - width_2 = -1000 THEN TRUE
ELSE FALSE
END AS column_name
FROM width_table ;
This will produce a column whose entries are either 1 if the difference is exactly +1000 or -1000, or 0 if the difference is anything else.
If you want to check if the difference is between 1000 and -1000, then you can use the following:
SELECT
CASE
WHEN width_1 - width_2 BETWEEN -1000 AND 1000 THEN TRUE
ELSE FALSE
END AS column_name
FROM width_table ;
Up front, I'm in a DB class and could use a hint to get closer to the correct answer.
In the ticket_old table there is the first and last name of technicians. Only two unique names.
In the new ticket table, I've got a tech_id column which needs the int matching the last_name of the tech found in the ticket_old table.
I've been trying to do this using the code below, which executes successfully and updates 0 rows.
UPDATE ticket,ticket_old
SET tech_id = (CASE WHEN ticket_old.techLast = 'name1' THEN 1
WHEN ticket_old.techLast = 'name2' THEN 2
END)
;
-edit, I also tried the following which runs and updates 0 rows.
UPDATE ticket,
(SELECT techLast FROM ticket_old WHERE techLast = 'name1') as src
SET ticket.tech_id = 1;
When Comparing two values,
Always use Double Equal marks:
SET tech_id = (CASE WHEN ticket_old.techLast == 'name1' THEN 1
WHEN ticket_old.techLast == 'name2' THEN 2
END)
I'm not sure if it is 'name' or "name". Try it.
In MySQL, is it possible to have two CASE statements in the SELECT clause, where the second CASE statement relies on the first CASE statement?
For example, consider the following query:
SELECT CASE WHEN `user`.`id` < 500 THEN 'awesome' ELSE 'lame' END
AS `status`
, CASE WHEN `status` = 'awesome' THEN 'You rock' ELSE 'You stink' END
AS `message`
FROM `user`
Basically, the user ID determines the status, and then the status determines the message.
However, as you might have guessed, this query generates this error:
Unknown column 'status'
The only solution I have found so far is two generate a temporary table, view, or subquery, and then the message is determined by the status returned in this subquery.
Is there a way to write this query without the use of a temporary table, view or subquery? I'm trying to avoid these constructs to keep the query simple and optimized if possible. Thank you!
You can, using temporary variables:
select
#status1 := (case
when user.id < 500 then 'awesome'
else 'lame'
end) as `status`,
(case
when #status1 = 'awesome' then 'You rock'
else 'You stink'
end) as message
from
user;
Some things you must know about temp variables:
They are always preceded by #
Avoid using reserved words, just in case (that's the reason I named the variable #status1
After the # symbol, they must begin with a letter, and must not have spaces
When you update them in a single query, they are updated "left-to-right" (talking about columns) and "first-to-last" (talking about rows). That can help you calculate cummulative sums or averages.
Example (for point 2):
select #t := 1, #t := #t + 1;
#t1 | #t2
----+----
1 | 2
Example (for point 3):
select myTable.x, #t := #t + myTable.x as cummulative_x
from
(select #t := 0) as init, -- You need to initialize the variable,
-- otherwise the results of the evaluation will be NULL
myTable
order by myTable.x -- Always specify how to order the rows,
-- or the cummulative values will be quite odd
-- (and maybe not what you want)
;
x | cummulative_x
---+---------------
1 | 1
1 | 2
2 | 4
3 | 7
Temporary variables can help you do some awesome things... feel free to play around ;)
Update
If you want to define conditions on the result of this query, there are two ways to do it:
Use the above query as a data-source for a second query (i.e. make it a subquery in the from clause of another query
Create a temp table and query on it
Option 1:
select a.*
from (
-- The query with temp variables defined
)
where -- ATTENTION: you need to write the references to the column names of the subquery
Option 2: (my personal favorite)
drop table if exists temp_my_temp_table;
create temporary table temp_my_temp_table
select
#status1 := (case
when user.id < 500 then 'awesome'
else 'lame'
end) as `status`,
(case
when #status1 = 'awesome' then 'You rock'
else 'You stink'
end) as message
from
user;
-- Add all appropriate indexes to this newly created table:
-- alter table temp_my_temp_table
-- add index idx_status(`status`),
-- add index idx_mess(message);
-- Make your queries on this new temp table
select * from temp_my_temp_table
-- where ...
;
Things you must know about a temp table:
They are created on RAM (by default, and only if the table is not too big)
They are only visible to the connection that created it
They are eliminated once the connection that created it is closed (or terminated in any way)
You can't use it more than once in a FROM clause. Other than that, you can use it as any other table in your database
Another update
Just by chance I came across this question and its answer. If you want to use the result of your column (calculated with temp variables) as a condition, MySQL allows this:
select
#status1 := (case
when user.id < 500 then 'awesome'
else 'lame'
end) as `status`,
(case
when #status1 = 'awesome' then 'You rock'
else 'You stink'
end) as message
from
user
having
`status` = 'awesome';
Instead of using where use having, and refer not to the temp variable, but to the alias of the column.
So I have a table containing two boolean columns called "master" and "edition". I did not make this table, somebody else made it, the table is already filled with a lot of data and I cannot change it so this is what I have to work with.
Now this is needed:
I need to do a SELECT statement, where I combine the master and edition columns into a new column. The new column should contain either the letter 'm' (when master is 1), 'e' (when edition is 1) or 'u' (when both are 0). Now I have no clue how to do that. Could anybody help me with this?
Try this:
select
CASE
WHEN master = 0 and edition = 0 THEN 'u'
WHEN master = 1 and edition = 0 THEN 'm'
WHEN master = 0 and edition = 1 THEN 'e'
ELSE '???' -- when either are one???
END
from myTable
If you need to update the value of a new column, you could use this query:
UPDATE
tablename
SET
new = CASE WHEN NOT (master OR edition) THEN 'u'
ELSE
CONCAT_WS('',
CASE WHEN master THEN 'm' END,
CASE WHEN edition THEN 'e' END)
END
Please see fiddle here.
This will return u if both values are false, m if master is true, e if edition is true, me if they are both true.
There are multiple ways to do this. Using CASE is the simplest, there is another one:
if there are no rows with master=1 and edition=1, this will work:
select *, 'm' from table where master=1
union
select *, 'e' from table where edition=1
union
select *, 'u' from table where edition=0 and master=0
I'm trying to update two fields of several rows at once but I can't determine the right syntax to do so, except for doing so with one field update.
Each row is identified by an id, and therefore I'm using a CASE statement.
I have this table:
tbl_accounts(id_account, nation_id,
group_id)
Now, the following query works for updating only one field:
UPDATE tbl_accounts SET nation_id = CASE id_account
WHEN 3 THEN 333
WHEN 5 THEN 555
ELSE nation_id END
The above will update the nation_id field of each corresponding row identified by its id_account.
And the following query doesn't work for updating two fields - please suggest a fix to the syntax. I'm trying to avoid using any SELECT/JOIN/etc':
UPDATE tbl_accounts SET nation_id = CASE id_account, group_id = CASE id_account
WHEN 3 THEN 3331, 3332
WHEN 5 THEN 5551, 5552
ELSE nation_id, group_id END
I could run this as two separate statements but I'm sure there's a way to combine the two into one.
Any help is highly appriciated!
It sounds like you are looking for something like this:
UPDATE tbl_accounts
SET nation_id =
CASE id_account
WHEN 3 THEN 3331
WHEN 5 THEN 5551
ELSE nation_id
END,
group_id =
CASE id_account
WHEN 3 THEN 3332
WHEN 5 THEN 5552
ELSE group_id
END
But doing separate updates is a sensible solution in this situation. The above query will require checking every row in the table to see if it matches the condition. If you have an index on id_account (and presumably you do as it appears to be the primary key) then it will be very fast to update a single row.
UPDATE tbl_accounts SET nation_id = 3331, groupid = 3332 WHERE id_account = 3
UPDATE tbl_accounts SET nation_id = 5551, groupid = 5552 WHERE id_account = 5