I have a table and its columns are id(int), order_id(int), partner_id(int)
Now I want to increment order_id based on partner_id ,
For Example
for partner 1, order_id's are 1,2,3
then if partner 2 is placing the order, the order_ids should start again from 1 and not from 4.
What is the best way to do so in mysql ? Should I read the last order id for a particular partner from db every time I want to create a new order ?
I am using mysql and sequelize
In a similar scenario for my case I 1st created a column on the order table called order_number.
Then created a mysql function to get the expected order_number base on parameter of the function and the order table.
Then on insert I just called the mysql function with appropriate parameter.
Here is what the mysql function looked like in my case:
Creating the function:
DELIMITER $$
CREATE FUNCTION `get_order_number`(partner_id VARCHAR(255)) RETURNS int(10)
BEGIN
DECLARE getCount INT(10);
SET getCount = (
SELECT COUNT(id)
FROM order_table
WHERE `partner_id` = partner_id
) + 1;
RETURN getCount;
END$$
DELIMITER ;
.
.
Implementation:
INSERT INTO (
id,
order_id,
pertner_id
) VALUES (
NULL,
get_order_number(10), -- 10 is partner_id
10 -- 10 is partner_id
);
.
.
Explanation of the function
1st pass partner_id as parameter for the function.
2nd inside the function I created a select query to get the number of how many orders have this partner created.
Finally adding one (1) with the returned number to get the last value.
.
.
Declaimer:
I have been using this function for over 3 years and have not got any issues yet. But this function has a weak point: When I submit the form simultaneously in two form/page at the same time (in millisecond) I get a deadlock error error for calling same function at the same time. Since I have moderate users I have not faced this error yet in real life situation.
I am using this function in plain mysql driver with node js, have not tested with sequelize.
Hope this helps.
Related
I've recently begun learning SQL and currently working on a project tracking the progress of the vaccination rollout. I'm trying to make an event which will automatically tally up the number of patients who have received both vaccine doses at a certain time each day.
This is what I've got so far. The event should return the timestamp and total number of second doses given (as defined in the patient_vaccine_history table), and add these entries to the vaccinated_tally table.
Workbench is kindly telling me that "COUNT" is not valid in line 17.
SET GLOBAL event_scheduler = ON;
CREATE TABLE vaccinated_tally(
ID INT NOT NULL AUTO_INCREMENT,
last_update TIMESTAMP,
fully_vaccinated_tally INT,
PRIMARY KEY (ID));
DELIMITER //
CREATE EVENT daily_tally
ON SCHEDULE AT NOW() + INTERVAL 1 SECOND
DO BEGIN
INSERT INTO vaccinated_tally(last_update)
VALUES (NOW());
INSERT INTO vaccinated_tally(fully_vaccinated_tally)
VALUES COUNT(pvh.nhs_number) -- this is the problem line
FROM patient_vaccine_history pvh
WHERE pvh.dose = 2
);
END//
DELIMITER ;
You would seem to want insert . . . select:
INSERT INTO vaccinated_tally (fully_vaccinated_tally)
SELECT COUNT(pvh.nhs_number) -- this is the problem line
FROM patient_vaccine_history pvh
WHERE pvh.dose = 2;
You are not inserting the timestamp. Perhaps you have a trigger or other mechanism for setting it.
I have a table called Contacts with a field called person_id that I have connected to a java application.
If no value is specified for person_id in the application, I want to select everything from the contacts table using a stored procedure.
The operation I want to perform is this:
Select * from Contacts where (person_id like "%")
For this I have written a stored procedure shown below:
Delimiter $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `selectTest2`(In p_id int(11))
BEGIN
if p_id = null then
set p_id = "%";
end if;
select * from Contacts where (person_id like p_id);
END $$
Delimiter ;
However when I run this procedure in my sql using the following
call selectTest2(null)
The table that is returned is blank. How do I make it show all the values in the table?
The parameter p_id gets its value from a text box in the application. If the user has entered an id, I want the procedure to show only that particular record else I want it to show all records.
What have I done wrong and how do I correct it? I am aware that p_id is an int however I tried the same thing with other fields of type varchar and the table failed to return any value.
Try using case statement in where clause like below
WHERE CASE WHEN p_id IS NOT NULL THEN person_id = p_id ELSE TRUE END
Hope this should solve your problem
I need help creating this particular stored function and call it by using the single select statement. Below are the questions with my answer. I think I got the first part right but I'm not sure. Any suggestions/advice? For the second question (part b), I'm calling the function incorrectly and can't get it to appear as specified in question/part b. Any advice? I would really appreciate the assistance.
Part A) Create a stored function called get_customer_balance which will return a customer’s balance from the membership table by passing in a membership number.
My Answer:
DELIMITER $$
CREATE FUNCTION get_customer_balance (membershipNo INT)
RETURNS dec
DETERMINISTIC
BEGIN
DECLARE CustBal dec;
SET CustBal = 0;
SELECT balance INTO CustBal
FROM membership
WHERE membership_id = membershipNo;
RETURN CustBal;
END$$
DELIMITER ;
Part B question
Membership Table. This is the original table of the problem (for reference guide)
create table membership
( membership_id int primary key,
balance decimal(10,2) not null
);
insert membership(membership_id,balance) values (1,1),(102,11),(103,109.25);
select membership_id,format(get_customer_balance(membership_id),2) as theBalance
from membership
where membership_id=102;
+---------------+------------+
| membership_id | theBalance |
+---------------+------------+
| 102 | 11.00 |
+---------------+------------+
Mysql Manual page on Create Proc and Functions
Calling your user defined function (UDF) would be like calling any built-in function. Even if it involved joins on tables with aliases (which the above does not show).
A much better example would be one in which there are two tables. A membership table, and a transaction table that needs summed. But that wasn't your schema.
Would you like to see such a thing?
I am a MySQL rookie and have been trying to create a stored procedure. The code below returns the error Error Code: 1172. Result consisted of more than one row. What am I doing wrong? (I'm using MySQL workbench)
CREATE DEFINER=`root`#`localhost` PROCEDURE `season_private_league_user`(
IN user_id INT,
OUT league_name VARCHAR(25),
OUT host_user VARCHAR(30))
BEGIN
DECLARE userteamid INT;
DECLARE var_league_name VARCHAR(25);
DECLARE var_host_user VARCHAR(30);
# Retrieve user team from user_id
SELECT CS_USER_TEAMS_ID INTO userteamid
FROM classicseasonmodel_classicseasonuserteam
WHERE user_id = user_id;
#LEAGUE NAME
SELECT classicseasonmodel_classicseasonprivateleague.private_league_name INTO var_league_name
FROM classicseasonmodel_classicseasonuserteamprivateleague
INNER JOIN classicseasonmodel_classicseasonprivateleague
ON classicseasonmodel_classicseasonuserteamprivateleague.private_league_id=classicseasonmodel_classicseasonprivateleague.CS_PRIVATE_LEAGUE_ID
WHERE user_team_id = userteamid;
#HOST_USER
SELECT classicseasonmodel_classicseasonprivateleague.host_user_id INTO var_host_user
FROM classicseasonmodel_classicseasonuserteamprivateleague
INNER JOIN classicseasonmodel_classicseasonprivateleague
ON classicseasonmodel_classicseasonuserteamprivateleague.private_league_id=classicseasonmodel_classicseasonprivateleague.CS_PRIVATE_LEAGUE_ID
WHERE user_team_id = userteamid;
SET league_name = var_league_name;
SET host_user = var_host_user;
END
CALL season_private_league_user(2, #league_name, #host_user);
SELECT #league_name AS league_name;
SELECT #host_user AS host_user;
Your column name and parameter name are identical. Rename your input parameter and change the command to this:
SELECT CS_USER_TEAMS_ID INTO userteamid
FROM classicseasonmodel_classicseasonuserteam
WHERE user_id = #user_id;
One of the SELECTs of you stored procedure that store the result in a variable returns more than one row, which returns in this error. This way you can only store single values in a variable, not multiple ones.
You can read about the SELECT...INTO statement here. The part that might be most interesting for you is:
The selected values are assigned to the variables. The number of
variables must match the number of columns. The query should return a
single row. If the query returns no rows, a warning with error code
1329 occurs (No data), and the variable values remain unchanged. If
the query returns multiple rows, error 1172 occurs (Result consisted
of more than one row). If it is possible that the statement may
retrieve multiple rows, you can use LIMIT 1 to limit the result set to
a single row.
I have a table task, this table contains information of recurring tasks, fox example daily tasks, so I repeat each task because I want to know the result of each task over time
1/1/2014 Get Pizza OK
1/2/2014 Get Pizza OK
1/3/2014 Get Pizza Error
1/4/2014 Get Pizza OK
For this I made a stored procedure
DELIMITER $$
CREATE DEFINER=`db`#`%` PROCEDURE `SP_repeat_task`()
BEGIN
INSERT INTO Task
(
date_of_assignment,
Some fields
)
SELECT
DATE_ADD(tas.date_of_assignment, INTERVAL 1 DAY),
another fields
FROM Task tas
WHERE tas.date_of_assignment=CURRENT_DATE and many conditions
)
;
END
This procedure is invoked every day 5 minutes before midnight. And produces something like this
The problem is that I have to insert the id of the records added in another table
For example
When I add 4 tasks in insert-select statement i need add these to another table
In my case, there can be multiple records for each task.
I can easily obtain id_person in my select, but not how to use it in the next insert.
I cant change the structure of the tables, I have only my stored procedure to work
I read about mysqli_insert_id, but not how to use it in my case
EDIT
based in b.b3rn4rd answer
When i add the other field in cursor select
DECLARE records_to_clone_cursor CURSOR FOR
SELECT `field1`, `field2`, `field3` FROM `Task` WHERE ... ;
In FETCH return more rows because as there is a one to many relationship in my tables
so the query returns with old fields
DECLARE records_to_clone_cursor CURSOR FOR
SELECT `field1`, `field2` FROM `Task` WHERE ... ;
And i tried change the prepared statement for a classic Insert-Select
SET #NEW_ID = LAST_INSERT_ID();
INSERT INTO Another_table
(
id_task,
id_person
)
SELECT tas.id_task,
pe.id_person
FROM Task tas
INNER JOIN Person pe
ON pe.id_person = tas.id_assigned
WHERE tas.id_task= #NEW_ID;
-- EXECUTE insert_responables USING #NEW_ID, #Var_3;
But does nothing, first prepared works well, and Select-Inser work in nornal query.
that I can do?
EDIT 2
if I need to insert the values, but because they are different cause the cursor query returns more records and these are duplicated by the number of records in the field is_person