how to update unique default option in one sql - mysql

i have table like this
-----------------------
id | name | is_default|
------------------------
1 | a | 1 |
2 | a | 0 |
3 | a | 0 |
4 | a | 0 |
-----------------------
now i want to change line 2(id =2) is_default to 1,and origin line(id =1) id_default to 0 at the same time,like the choose default option in list in UI.
1.can i do this in one sql statement?
2.if it is possible,how to write the sql statement or how to write in mybatis mapper.xml?
Springboot with mybatis ,sql statement write in mapper.xml
#Data
pulbic class Option{
private Integer id;
private String name;
private Boolean isDefault;
}
how to write the mybatis or mysql statement?

You may use a CASE expression:
UPDATE yourTable
SET is_default = CASE WHEN id = 1 THEN 0 ELSE 1 END
WHERE id IN (1, 2);
Or, if you intended to just toggle the default values for id 1 and 2, then try:
UPDATE yourTable
SET is_default = CASE WHEN is_default = 1 THEN 0 ELSE 1 END
WHERE id IN (1, 2);

Tim's answer is fine. If the values are only 0/1, you can simplify it to:
UPDATE t
SET is_default = 1 - is_default
WHERE id IN (1, 2);

Related

Conditional table updates

Consider the following table.
myTable
+----+-----------+------------------------------------+
| Id | responseA | responseB |
+----+-----------+------------------------------------+
| 1 | | {"foo":"bar","lvl2":{"key":"val"}} |
+----+-----------+------------------------------------+
where:
Id, INT (11) PRIMARY
responseA, TEXT utf8_unicode_ci
responseB, TEXT utf8_unicode_ci
Let's say that I want to conditionally update the table with some outside data. The conditions are:
• if there's nothing in responseA, populate it with the outside data, otherwise
• if there is something in responseA, leave it as it is, and populate responseB with the outside data
I was pretty much convinced that I could just do this to get what I want:
UPDATE myTable
SET
responseA = IF(TRIM(responseA) = '','foo',TRIM(responseA)),
responseB = IF(TRIM(responseA) != '','foo',TRIM(responseB))
WHERE Id = 1
However, this updates both responseA and responseB to the same value - foo, making the table:
myTable
+----+-----------+-----------+
| Id | responseA | responseB |
+----+-----------+-----------+
| 1 | foo | foo |
+----+-----------+-----------+
I was expecting my table to look like this after the update:
myTable
+----+-----------+------------------------------------+
| Id | responseA | responseB |
+----+-----------+------------------------------------+
| 1 | foo | {"foo":"bar","lvl2":{"key":"val"}} |
+----+-----------+------------------------------------+
What am I misunderstanding, and how can I achieve this conditional update? Do the updates happen sequentially? If so, I guess that would explain why both of the fields are updated.
UPDATE TABLE
SET responseA = CASE WHEN responseA IS NULL
THEN #data
ELSE responseA
END,
responseB = CASE WHEN responseA IS NULL
THEN responseB
ELSE #data
END
;
here your changed query
UPDATE myTable
SET
responseB = IF(TRIM(responseA) != '','foo',TRIM(responseB)),
responseA = IF(TRIM(responseA) = '','foo',TRIM(responseA))
WHERE Id = 1
It seems the value of responseA is changed before the IF() for responseB is evaluated.
One possible solution is to do a simple UPDATE:
UPDATE mytable SET responseA = ? WHERE id = 1
Then adjust the columns in a trigger, where you have access to both the original and the new value of the columns:
CREATE TRIGGER t BEFORE UPDATE ON mytable
FOR EACH ROW BEGIN
IF TRIM(OLD.responseA) != '' THEN
SET NEW.responseB = NEW.responseA;
SET NEW.responseA = OLD.responseA;
END IF;
END
(I have not tested this.)
I am also assuming that your test for '' (empty string) instead of NULL is deliberate, and that you know that NULL is not the same as ''.
The key point in the UPDATE statement is that you should update first the column responseB, so that column responseA retains its original value which can be checked again when you try to update it:
UPDATE myTable
SET responseB = CASE WHEN TRIM(responseA) = '' THEN responseB ELSE 'foo' END,
responseA = CASE WHEN TRIM(responseA) = '' THEN 'foo' ELSE responseA END
WHERE Id = 1;

How to concat two rows into string from a result set in MySql?

Basicly this is my mysql query:
select distinct(shipment_tag) from ir_shipment_registry where shipment_id = '2020111'
and the result set:
| shipment_tag |
+--------------+
| Truck |
| Equipment |
| |
How can I concat the two result set into string so that i can assign it to a variable? I tried
SET #purchasetype = (select distinct(shipment_tag) from ir_shipment_registry where shipment_id = '2020111')
but it returns and error says: Subquery returns more than 1 row.
I want something in my variable like : #purchasetype = "Truck, Equipment".
Perhaps use GROUP_CONCAT here:
SET #purchasetype = (SELECT GROUP_CONCAT(shipment_tag SEPARATOR ', ') FROM ir_shipment_registry WHERE shipment_id = '2020111');

MYSQL select function from field value?

I have a table and its data are mentioned below :
id | function
1 | current_date
2 | UUID()
3 | RAND()
Structure of the table is
id int, function varchar(50)
Query : select * from func_table;
My excepted result is
id | function
1 | 2020-08-24
2 | 70d6cffc-ae01-11ea-80ca-c11529136ae3630
3 | 0.982584554752
Thanks in advance.
You can use a giant case expression:
select (case when function = 'current_date' then cast(current_date as char)
when function = 'uuid()' then cast(uuid as char)
when function = 'rand()' then cast(rand as char)
end) as value
If you actually want to evaluate the function directly, then you probably have a problem with your data model. SQL does not directly support such functionality.

How to select static values on mysql select query?

I am new to mysql, here i am trying to get data from database table.
select id,txnid,amount,status from txn_details;
With above query Getting data successfully but status column getting 0 or 1 or 2, but i want 0 as failed, 1 as success and 2 as not processed.
How to change my query?
You can use a case
select id, txnid, amount,
case when status = 0 then 'failed'
when status = 1 then 'success'
else 'not processed'
end as status
from txn_details;
We can use an expression in the SELECT list. It could be a searched CASE expression e.g.
SELECT CASE t.status
WHEN 0 THEN 'failed'
WHEN 1 THEN 'success'
WHEN 2 THEN 'not processed'
ELSE 'unknown'
END AS status_name
, t.status
, t.amount
, t.txnid
FROM txn_details t
This approach is ANSI-92 standards compliant, and will work in most relational databases.
There are some other MySQL specific alternatives, such as the ELT function ...
SELECT ELT(t.status+1,'failed','success','not processed') AS status_name
, t.status
, t.amount
, t.txnid
FROM txn_details t
https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_elt
If you prefer a central point of maintenance (ie you prefer not to recode all your queries when a new status comes along) you could create a status table and either use a join or sub query to get the values, alternatively you could create a function, for example
drop table if exists txn_details,txn_status;
create table txn_details(id int, txnid int, amount int , status int);
insert into txn_details values
(1,1,10,1),(2,1,10,2),(3,1,10,4);
create table txn_status (id int, statusval varchar(20));
insert into txn_status values
(1,'success'),(2,'not processed'), (3,'failed');
drop function if exists f;
delimiter $$
create function f(instatus int)
returns varchar(20)
begin
declare rval varchar(20);
return (select
case when instatus = 1 then 'success'
when instatus = 2 then 'not processed'
when instatus = 3 then 'failed'
else 'Unknown'
end
);
select t.*,coalesce(ts.statusval,'Unknown') status
from txn_details t
left join txn_status ts on ts.id = t.status;
select t.*,coalesce((select statusval from txn_status ts where ts.id = t.status),'Unknown') status
from txn_details t;
Note the use of coalesce in case a status is not found.
Both produce this result
+------+-------+--------+--------+---------------+
| id | txnid | amount | status | status |
+------+-------+--------+--------+---------------+
| 1 | 1 | 10 | 1 | success |
| 2 | 1 | 10 | 2 | not processed |
| 3 | 1 | 10 | 4 | Unknown |
+------+-------+--------+--------+---------------+
3 rows in set (0.00 sec)
Using the function like this
select t.*, f(status) as status
from txn_details t;
also produces the same result.
Of course using a status table or a function means you have to communicate their availability and enforce their use.
I would also consider the using a foreign key constraint in txn_details to cut down on the number of unknown values and put procedures in place to stop people adding new status codes at will without going through change control
The following query would work. It uses CASE ... END to determine and return values for the virtual column status.
SELECT id,txnid,amount,
CASE
WHEN status = 0 THEN 'failed'
WHEN status = 1 THEN 'success'
WHEN status= 2 THEN 'not processed'
END AS status
FROM txn_details;

How to achieve default value if column value is NULL?

I want to retrieve some column values from table with these conditions.
If value is NULL (or) Empty String , return some user defined value
If not above condition , return it's value.
How can I figure it out ?
Here is my Table query..
CREATE TABLE AUCTION_CAR_BID(
bid_seq bigint NOT NULL AUTO_INCREMENT,
auction_car_seq bigint NOT NULL,
bid_group_seq bigint NOT NULL,
bid_price int DEFAULT 0 NOT NULL,
over_bid_price int DEFAULT -1 NOT NULL,
result_id int DEFAULT 0 NOT NULL,
remark varchar(500),
PRIMARY KEY (bid_seq))
ENGINE = InnoDB DEFAULT CHARACTER SET utf8;
Here is my efforted codes to get it..
SELECT
COALESCE(OVER_BID_PRICE, -1)
FROM
AUCTION_CAR_BID
WHERE
BID_SEQ = 2354435345;
Another :
SELECT
CASE
WHEN OVER_BID_PRICE IS NULL
OR TRIM(OVER_BID_PRICE) = '' THEN -1
ELSE OVER_BID_PRICE
END OVER_BID_PRICE
FROM
AUCTION_CAR_BID
WHERE
BID_SEQ = 2354435345;
But I always get empty String value(not -1) if given id is not in my table.
Any suggestions would be really appreciated !
If you write this:
SELECT
COALESCE(OVER_BID_PRICE, -1)
FROM
AUCTION_CAR_BID
WHERE
BID_SEQ = 2354435345;
The results can be two types.
First result: Your query no returns rows! Your WHERE condition is unsatisfact so you'll read NULL
Second result: Your query returns rows but the value of your field is NULL, your COALESCE works fine in this case
To resolve you can try this:
SELECT COALESCE(
(SELECT
COALESCE(OVER_BID_PRICE, -1)
FROM AUCTION_CAR_BID
WHERE BID_SEQ = 2354435345)
,-1);
Tell me if it's OK
How about this:
select
case when price is null or id <> 1
then -1
else price
end price
from mytable
DROP TABLE prices;
CREATE TABLE prices (price_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,price INT NULL);
INSERT INTO prices (price) VALUES (' '),(''),(NULL);
SELECT * FROM prices;
+----------+-------+
| price_id | price |
+----------+-------+
| 1 | 0 |
| 2 | 0 |
| 3 | NULL |
+----------+-------+
SELECT price_id,COALESCE(price,-1) price FROM prices;
+----------+-------+
| price_id | price |
+----------+-------+
| 1 | 0 |
| 2 | 0 |
| 3 | -1 |
+----------+-------+
If there's no row for USER_SEQ = 2354435345 in your table there's no row returned. But aggregate functions always return a row even if the result is empty :-)
SELECT
COALESCE(MIN(OVER_BID_PRICE), -1)
FROM
USER_PARAM
WHERE
USER_SEQ = 2354435345;