MySQL twice update with one command - mysql

In the below Update command i want to set all delay field to 0 and an id of 2 must be update to 1
UPDATE `tsms_entry_exit`
SET `delay`=(
CASE `delay`
WHEN `id` = 2 THEN 1
ELSE 0
END
)
WHERE user_id = 1
Otherwise:
UPDATE `tsms_entry_exit`
SET `delay`=0
WHERE user_id = 1;
UPDATE `tsms_entry_exit`
SET `delay`=0
WHERE user_id = 1 AND id = 2
How do i update twice in one update command?

If I understand very well, might be you want this
UPDATE `tsms_entry_exit`
SET `delay`= CASE WHEN `id` = 2 THEN 1
ELSE 0
END
WHERE user_id = 1

This is how you can use the update command
update tsms_entry_exit set
delay =
case when id = 2 then 1
else 0
end
where user_id = 1
DEMO

Related

Find the hierarchy tree of parent and childs and their childs - MySQL Query

I have a table with different zone names with Id's and their parent id's. I want to generate report with the hierarchies. Like below.
Table: Groups
ID Name ParentID
1 Corporate NULL
2 Zone 1 1
3 Zone 2 1
4 Zone 3 1
5 Zone 4 1
6 Telangana 2
7 Hyderabad 6
8 Khammam 6
9 Odisha 3
10 Bhubaneshwar 9
Using above table now I want to generate report. If I select corporate then I need to get all data. If I select Zone 1 I need to get all child relations as well.Like Below
Zone 1, Telangana, Hyderabad, Khammam
Please help me on writing query for this.
Working with hierarchical data in SQL is tricky. I suggest you to use nested sets model and modify your table: add left and right columns. Update them when adding, updating and deleting the data (this is the price for easy SELECTs). When you do it, getting all the children of record #2 will be easy:
SELECT `left`, `right` FROM `table` WHERE id=2;
-- here we get $left and $right
SELECT * FROM `table` WHERE `left`>=$left AND `right` <= $right;
I've found the answer for my above question. This can be achieved by using Stored Procedure.
DELIMITER $$
DROP PROCEDURE IF EXISTS getHierarchy_proc $$
CREATE PROCEDURE getHierarchy_proc (IN GivenID INT, OUT ids VARCHAR(10000))
BEGIN
DECLARE int_check VARCHAR(1000);
DECLARE is_exit TINYINT(1) DEFAULT 0;
DROP TABLE IF EXISTS bu_tmp;
CREATE TEMPORARY TABLE bu_tmp(
bu_id INT(11) NOT NULL,
is_upd TINYINT(1) NOT NULL DEFAULT 0);
SET SESSION GROUP_CONCAT_MAX_LEN = 100000;
INSERT INTO bu_tmp (bu_id)
SELECT GivenID;
SET int_check = (SELECT bu_id FROM bu_tmp WHERE bu_id = GivenID AND is_upd = 0);
SET is_exit = 1;
REPEAT
IF is_exit > 0 THEN
INSERT INTO bu_tmp (bu_id,is_upd)
SELECT ID,0 FROM Groups WHERE FIND_IN_SET(parent_id , int_check);
UPDATE bu_tmp SET is_upd = 1 WHERE FIND_IN_SET(bu_id,int_check);
SET is_exit = (SELECT COUNT(*) FROM bu_tmp WHERE is_upd = 0);
SET int_check = (SELECT GROUP_CONCAT(bu_id) FROM bu_tmp WHERE is_upd = 0);
END IF;
UNTIL is_exit = 0 END REPEAT;
SET ids = (SELECT GROUP_CONCAT(lew.le_wh_id)
FROM bu_tmp bu JOIN legalentity_warehouses lew
WHERE bu.bu_id = lew.bu_id
AND lew.dc_type = 118001
AND lew.status = 1);
END$$
DELIMITER ;

Stored Procedure in MSSQL for joining two tables

I am trying to write a Stored Procedure to authenticate login.
I have two tables which will hold the data table structure given as below.
Table : UserMaster
Userid Password IsActive
1111 xyz 1
2222 abc 0
Table : Userdetailes
Userid Status StartDate EndDate
1111 1 2015-08-01 2015-08-24
2222 0 2015-08-01 2015-08-10
this is how the data is stored in two tables
I want to write a stored procedure to view data from using join
Try something like this.....
CREATE PROCEDURE [dbo].[uspauth]
#LoginId NVARCHAR(30)
,#ActiveStatus INT OUTPUT
AS
BEGIN
SET NOCOUNT ON
BEGIN TRY
--1 - Both Active, 2 - User InActive & Package Active, 3 - User Inactive & Package Inactive , 4 - Not authosrised
DECLARE #Username VARCHAR(40), #isAct Bit,#stat Bit
IF NOT EXISTS(SELECT 1 FROM UserSet where UserID = #LoginId)
BEGIN
RAISERROR('login does not exist',16,1)
RETURN;
END
SELECT #Username = ISNULL(UserID,0), #isAct = ISNULL(IsActive, 0) from UserSet where UserID = #LoginId)
Select #stat = ISNULL([status],0) from Subscription where UserID = #LoginId
and (DateOfStart <= CAST(GETDATE() as DATE) or DateOfStart is NULL)
and (DateOfEnd >= Cast(GETDATE() as DATE) or DateOfEnd is NULL)
IF (#isAct = 1 AND #stat = 1) --1 - Both Active
BEGIN
SET #ActiveStatus = 1;
END
ELSE IF (#isAct = 0 AND #stat = 1) -- 2 - User InActive & Package Active
BEGIN
SET #ActiveStatus = 2;
END
ELSE IF (#isAct = 1 AND #stat = 0) -- 3 - User Active & Package Inactive
BEGIN
SET #ActiveStatus = 3;
END
ELSE IF (#isAct = 0 AND #stat = 0) -- 4 - Not authosrised
BEGIN
SET #ActiveStatus = 4;
END
END TRY
BEGIN CATCH
IF ##TRANCOUNT > 0
BEGIN
ROLLBACK TRAN
END
EXEC uspProcErrorLog
END CATCH
END
The last if else code block can be simplified with case expression:
set #status = case when #isAct = 1 and #stat = 1 then 1
when #isAct = 0 and #stat = 1 then 2
when #isAct = 1 and #stat = 0 then 3
when #isAct = 0 and #stat = 0 then 4
end
return #status

MySQL increment values of 1

I'm attempting to update some values in my database, they are currently empty and I want to add them in increments of 1 starting with 1.
Example
Value
1
2
3
4
5
6
I have tried this but it doesn't work.
UPDATE catalog_product_entity_varchar
SET value = '1' + 1
WHERE attribute_id = 136
Any suggestions?
EDIT: I'm using a MySQL server with phpmyadmin
This is what worked in the end.
SET #i := 1;
UPDATE catalog_product_entity_varchar
SET value = #i:=#i+1
WHERE attribute_id = 136;
Assuming SQL server, you could do this:
http://sqlfiddle.com/#!6/ebbba/4
declare #counter int
set #counter = 0
UPDATE catalog_product_entity_varchar
SET value = #counter,
#counter = #counter + 1
WHERE attribute_id = 136
Try something like this (SQL Server only):
with [incremented] as
(
select attribute_id, row_number() over(order by attribute_id) [no], value
from catalog_product_entity_varchar
)
UPDATE [incremented]
SET value = [no];
Check SqlFiddle

MySQL TRIGGER with an IF statement determined by an IN

I'am constructing a trigger
CREATE TRIGGER `address_control_update` BEFORE UPDATE ON `orders_shipping`
FOR EACH ROW
BEGIN
SET #error_msg_id := (SELECT `error_msg_id` FROM `orders_err` WHERE orderID = OLD.orderID);
IF(LENGTH(NEW.ShippingName) = 0 OR NEW.ShippingName IS NULL) THEN
INSERT INTO `orders_err` (orderID,error_msg_id) VALUES(NEW.orderID,100) ON DUPLICATE KEY UPDATE complete=false;
ELSEIF (100 IN (SELECT #error_msg_id)) THEN
UPDATE `orders_err` SET complete = true WHERE orderID = OLD.orderID AND error_msg_id = 100;
END IF;
END;//
Where I would like to, first see if there is any error_msg_id on the orderID and later use this in the elseif statement to see if a possible error has been completed.
It works if i do this
IF(LENGTH(NEW.ShippingName) = 0 OR NEW.ShippingName IS NULL) THEN
INSERT INTO `orders_err` (orderID,error_msg_id) VALUES(NEW.orderID,100) ON DUPLICATE KEY UPDATE complete=false;
ELSEIF EXISTS(SELECT * FROM orders_err WHERE orderID = OLD.orderID AND error_msg_id = 100) THEN
UPDATE `orders_err` SET complete = true WHERE orderID = OLD.orderID AND error_msg_id = 100;
END IF;
But i would like to only call the select once if possible, since i have 12 similar if statements on other columns in the orders_shipping table.
On update i get the error: ERROR 1242: 1242: Subquery returns more than 1 row
Thanks in advance
One of possible solutions is to concatenate ids to one string separated by commas using GROUP_CONCAT(..) function - then first SELECT statement will return one row. To test whether an id is in the string use FIND_IN_SET(..) function:
CREATE TRIGGER `address_control_update` BEFORE UPDATE ON `orders_shipping`
FOR EACH ROW
BEGIN
SET #error_msg_ids = (
SELECT GROUP_CONCAT(DISTINCT `error_msg_id`)
FROM `orders_err`
WHERE orderID = OLD.orderID
GROUP BY orderID);
IF(LENGTH(NEW.ShippingName) = 0 OR NEW.ShippingName IS NULL) THEN
INSERT INTO `orders_err` (orderID,error_msg_id) VALUES(NEW.orderID,100) ON DUPLICATE KEY UPDATE complete=false;
ELSEIF (FIND_IN_SET(100, #error_msg_ids)) THEN
UPDATE `orders_err` SET complete = true WHERE orderID = OLD.orderID AND error_msg_id = 100;
END IF;
END;//
Also I think there exists other possibilities. For example you can write code without SELECT statement:
IF(LENGTH(NEW.ShippingName) = 0 OR NEW.ShippingName IS NULL) THEN
INSERT INTO `orders_err` (orderID,error_msg_id) VALUES(NEW.orderID,100) ON DUPLICATE KEY UPDATE complete=false;
ELSE
UPDATE `orders_err` SET complete = true WHERE orderID = OLD.orderID AND error_msg_id = 100;
END IF;
why - because you use the same filtering conditions in SELECT and in UPDATE - so there no need to test the same conditions before update.

Counting with MySQL

Is there a way to count an Int in a MySQL Update Query?
Currently i have
UPDATE mails SET uid = 4275
and i want something like
UPDATE mails SET uid = (4275++)
Do you want to do something like this?
SELECT #i:=425;
UPDATE mails SET uid = #i:=#i+1;
UPDATE mails SET uid = uid + x
x meaning any number
I didn't get your question properly but I am just answering as I understood
UPDATE mails SET uid = uid + 1
i.e to increment current uid by the lastuid + 1
If you need to update the table so that increment each uid with 1 then you can do this:
UPDATE mails
SET uid = uid + 1;
But if you need to increament each value uid by an incremental value try this:
SET #counter = 0;
UPDATE mails m1
INNER JOIN
(
SELECT *, (#counter := #counter +1) as counter
FROM mails
) m2 ON m1.uid = m2.uid
SET m1.uid = m1.uid + m2.counter
And if you want to count from 4275 on, just set the counter to SET #counter = 4275
UPDATE mails SET uid = uid +1 will add 1 to every uid column.
try
UPDATE mails SET uid = uid+1
where uid = 4275
You can keep your own counter
declare #curr_uid integer;
SET #curr_uid = 4275; -- initial uid
update mails
set uid = #curr_uid , #curr_uid = #curr_uid + 1