I'm creating a Queuing system, with mysql and vb.net that prints ticket no.
Scenario:
Ticket will proceed to billing (2 windows), then after that proceed to cashier (2 windows) when ticket is called on dashboard, then after cashier - ticket will be closed.
My tbl_ticket
I have here my MySql query that assign a ticket to a cashier window. this works for a single cashier user. but I have 2 cashier.
Cashier 1 = (#agentID = 1) and Cashier 2 = (#agentID = 2)
UPDATE tbl_ticket, (
SELECT * FROM tbl_ticket WHERE current_agent = 0 AND cashier_stat = 1 AND DATE(tag_time) = DATE(NOW()) ORDER BY tag_time ASC LIMIT 1 FOR UPDATE
) as ticket
SET tbl_ticket.current_agent = #agentID
WHERE tbl_ticket.id = ticket.id;
I update tbl_ticket with agentid on tbl_ticket.current_agent for assigning what ticket to assess for Cashier 1 or Cashier 2.
Does this query can ensure that if two cashier execute this in the same time they will not be assigned in the same number in sequence? I want 2 cashier to get different ticket at the same time.
Related
When 2 client tries to update the same row at the same time only one is submitted and the other one is rejected so i want to create a queue to update one by one and sorry for bad English
I’m student I don’t know how to do is there any other way
I created java system for inventory i have store when 2 client tries to buy the same product at The same time , it must update the row for example product_quantity =10 If client 1 and client 2 tries to buy at the same time client 1 buy 2 it must be 10-2=8 and client 2 buy 3 it must 8-3=5 but the result appears 8 or 7 it mean accept only one this my code (select product_quantity from store where store_id = barcode)
If quantity > 0 { ( update store set products_quantity = ( sumquantity - quantitytobuy) where storeid = barcode
}
Requirements:
1. All "Users" have 5 fixed set of same "Services" which they are supposed to rate.
2. Given the userId, display all the Services and their corresponding "Ratings".
3. Rating would be from a scale of 1 - 5 only
4. Ratings can be updated anytime by the user for any of his Service.
I am no SQL/DB expert and I had this question up in stacks for which I got answer from Raj here ER Model of User Ratings
This is the ER I finalized (open for correction).
My Fetch Query: Get all the services and their corresponding for a userId (say userId = 1)
SELECT service.service_id, service.name, usr.ratings
FROM services service,
ratings ratings,
userservices_ratings usr,
user user,
user_services us
where
us.userid = user.uid and
us.serviceid = service.serviceid and
usr.usid = us.id and
usr.rid = ratings.rid and
user.id = 1
The above query will return all the services and ratings, only if User has rated the service. For services which are unrated don't make it to result set. So I assume I should pre-populate unrated services with a default value say 0?
All users will have fixed set of 5 services all the time, do I write a trigger to create his entry into User_Services table whenever a User is created?
How would the create/update query look if for example a Userid = 1, rates = 3 for serviceId = 1?
Any flaw in the schema?
You can standard format of Rating Schema here https://schema.org/Rating
You can pick required columns from this
Please help by writing a SQL-script that will collate data.
A key difficulty - need to create an additional column on which sorting will take place.
I tried to describe the situation as detailed as possible.
Let's get started. There is a table of the following form:
We will receive a user ID and return data, only those who do not have he, but there are others.
Next step: sort by artificially created column.
Next, I'll step by step.
So what do I mean by artificial column:
This column will contain the difference between the estimates. So to get it - you need to first perform a number of actions:
According to the information which is like set the user and at other user to calculate the difference in assessment, and get an average score.
The following two pictures show the same data and then the calculation itself, it seems to me - it's pretty simple.
Calculation of this column is as follows:
User with 2nd id:
1: 5 - 1 = 4;
2: 2 - 9 = -7;
3: next data what is in user 1 - absent in user 2, and we ease pass it;
User with 3rd id:
1: 3 - 1 = 2;
2: the next data's is absent in user with 3rt id;
3: 8 – 9 = -1;
4: 6 – 2 = 4;
5: passed;
End in the end:
User_2 will have new mark = -1.5
User_3 will have new mark = 1.66666
And in the end I need to return the table:
But that's not all. Often, the data will be duplicated and I'd like to get average results from the data obtained. Please look at the following example:
And this is the end. I really need your help, experts. I teach sql code myself, but it is very difficult for me.
Had the idea of making the script as follows:
SELECT d.data, (d.mark + myCount(d.user, 1)) newOrder
FROM info d
WHERE -- data from user_1 NOT equal data from other users
ORDER BY newOrder;
But the script will execute a lot of time, because it uses its own function that could do with a query to each user, and not to record. I hope someone will be able to cope with this task.
Following your steps:
First, we need to isolate the data from the selected user (let's assume it's 1):
CREATE TEMP TABLE sel_user AS
SELECT data, mark FROM info d WHERE user = 1;
Now, we calculate the mark for every other user (again, the selected user is 1):
SELECT d.user user, d.mark - s.mark mark
FROM info d JOIN sel_user s USING (data)
WHERE d.user <> 1;
Result:
user mark
---------- ----------
2 4
2 -7
3 2
3 -1
3 4
We can query just the average:
SELECT d.user user, AVG(d.mark - s.mark) mark
FROM info d JOIN sel_user s USING (data)
WHERE d.user <> 1 GROUP BY user;
user mark
---------- ----------
2 -1.5
3 1.66666666
But you still want to do calculations with the marks that do not correspond to user 1:
SELECT d.user user, mark FROM info d
WHERE d.user <> 1 AND d.data NOT IN (SELECT data FROM sel_user);
user mark
---------- ----------
2 4
3 3
3 10
Specifically, you want to add the previously calculated average to each row:
SELECT d.user user, d.data, d.mark + d2.mark AS neworder FROM info d JOIN (
SELECT d.user user, AVG(d.mark - s.mark) mark
FROM info d JOIN sel_user s USING (data)
WHERE d.user <> 1 GROUP BY user
) d2 USING (user)
WHERE d.data NOT IN (SELECT data FROM sel_user)
ORDER BY neworder DESC;
user data neworder
---------- ---------- ----------------
3 6 11.6666666666667
3 3 4.66666666666667
2 5 2.5
And your last request is to get the average for each data:
SELECT data, AVG(neworder) final FROM (
SELECT d.user user, d.data, d.mark + d2.mark AS neworder FROM info d JOIN (
SELECT d.user user, AVG(d.mark - s.mark) mark
FROM info d JOIN sel_user s USING (data)
WHERE d.user <> 1 GROUP BY user
) d2 USING (user)
WHERE d.data NOT IN (SELECT data FROM sel_user)
)
GROUP BY data
ORDER BY final DESC;
data final
---------- ----------------
6 11.6666666666667
3 4.66666666666667
5 2.5
App goal
Send messages from retailers to registered customers mobile via GCM
DB architecture
I have a customers table and a related customers_realtions table with the following fields: id, customerID, retailerID, isBlocked
Required outcome
A customer can register for a specific retailer, or for a wildcard (all of them).
In case one registers for all the retailers, he has an option to block a specific retailer from sending future messages, effectively creating a blacklist.
DB values for each status
When a customer registers for a single retailer retailerID is assigned with the retailer ID.
When a customer register for all of the retailers retailerID equals 1.
When a customer blocks a retailer there are two options:
a. if he registered to this specific retailer before the isBlocked field is updated to 1 (true)
b. if he registered to all retailers before a new row is created for this retailer and isBlocked is set to 1 (true)
The challenge
When sending the message the SELECT query should include the customers that has a retailerID of 1 and does not have the sending retailerID when isBlocked equals 1.
For example, in this situation
id customerID retailID isBlocked
129 46 111 1
128 46 1 0
I don't want the customer to be selected even if the retailerID is 111
My attempt
SELECT * FROM customers_relations
WHERE
(retailID=111
OR
(retailID=1
AND
(SELECT isBlocked FROM `customers_relations` WHERE customerID=46 AND retailID=111)=0))
AND
NOT isBlocked
Question
While this is working for a single customer for whom I know the ID in advance, I am struggling to figure a way of writing a similar query for multiple customers.
I think of this as an aggregation query. You want to look through all the rows that are not blocked for a customer and determine whether retailer 111 is available or all retailers are available:
SELECT customerId
FROM customers_relations cr
WHERE isBlocked = false
GROUP BY customerId
HAVING MAX(retailId = 111) > 0 OR
MAX(retailId = 1) > 0;
I notice that your question actually says that a new row is created in customer_relations when someone is blocked. The above assumes there is one row. To handle the case when a block on any row would cause a block, then:
SELECT customerId
FROM customers_relations cr
GROUP BY customerId
HAVING (MAX(retailId = 111) > 0 OR
MAX(retailId = 1) > 0
) AND
MAX(retailId = 111 AND isblocked = true) = 0;
I have a table of surveys which contains (amongst others) the following columns
survey_id - unique id
user_id - the id of the person the survey relates to
created - datetime
ip_address - of the submission
ip_count - the number of duplicates
Due to a large record set, its impractical to run this query on the fly, so trying to create an update statement which will periodically store a "cached" result in ip_count.
The purpose of the ip_count is to show the number of duplicate ip_address survey submissions have been recieved for the same user_id with a 12 month period (+/- 6months of created date).
Using the following dataset, this is the expected result.
survey_id user_id created ip_address ip_count #counted duplicates survey_id
1 1 01-Jan-12 123.132.123 1 # 2
2 1 01-Apr-12 123.132.123 2 # 1, 3
3 2 01-Jul-12 123.132.123 0 #
4 1 01-Aug-12 123.132.123 3 # 2, 6
6 1 01-Dec-12 123.132.123 1 # 4
This is the closest solution I have come up with so far but this query is failing to take into account the date restriction and struggling to come up with an alternative method.
UPDATE surveys
JOIN(
SELECT ip_address, created, user_id, COUNT(*) AS total
FROM surveys
WHERE surveys.state IN (1, 3) # survey is marked as completed and confirmed
GROUP BY ip_address, user_id
) AS ipCount
ON (
ipCount.ip_address = surveys.ip_address
AND ipCount.user_id = surveys.user_id
AND ipCount.created BETWEEN (surveys.created - INTERVAL 6 MONTH) AND (surveys.created + INTERVAL 6 MONTH)
)
SET surveys.ip_count = ipCount.total - 1 # minus 1 as this query will match on its own id.
WHERE surveys.ip_address IS NOT NULL # ignore surveys where we have no ip_address
Thank you for you help in advance :)
A few (very) minor tweaks to what is shown above. Thank you again!
UPDATE surveys AS s
INNER JOIN (
SELECT x, count(*) c
FROM (
SELECT s1.id AS x, s2.id AS y
FROM surveys AS s1, surveys AS s2
WHERE s1.state IN (1, 3) # completed and verified
AND s1.id != s2.id # dont self join
AND s1.ip_address != "" AND s1.ip_address IS NOT NULL # not interested in blank entries
AND s1.ip_address = s2.ip_address
AND (s2.created BETWEEN (s1.created - INTERVAL 6 MONTH) AND (s1.created + INTERVAL 6 MONTH))
AND s1.user_id = s2.user_id # where completed for the same user
) AS ipCount
GROUP BY x
) n on s.id = n.x
SET s.ip_count = n.c
I don't have your table with me, so its hard for me to form correct sql that definitely works, but I can take a shot at this, and hopefully be able to help you..
First I would need to take the cartesian product of surveys against itself and filter out the rows I don't want
select s1.survey_id x, s2.survey_id y from surveys s1, surveys s2 where s1.survey_id != s2.survey_id and s1.ip_address = s2.ip_address and (s1.created and s2.created fall 6 months within each other)
The output of this should contain every pair of surveys that match (according to your rules) TWICE (once for each id in the 1st position and once for it to be in the 2nd position)
Then we can do a GROUP BY on the output of this to get a table that basically gives me the correct ip_count for each survey_id
(select x, count(*) c from (select s1.survey_id x, s2.survey_id y from surveys s1, surveys s2 where s1.survey_id != s2.survey_id and s1.ip_address = s2.ip_address and (s1.created and s2.created fall 6 months within each other)) group by x)
So now we have a table mapping each survey_id to its correct ip_count. To update the original table, we need to join that against this and copy the values over
So that should look something like
UPDATE surveys SET s.ip_count = n.c from surveys s inner join (ABOVE QUERY) n on s.survey_id = n.x
There is some pseudo code in there, but I think the general idea should work
I have never had to update a table based on the output of another query myself before.. Tried to guess the right syntax for doing this from this question - How do I UPDATE from a SELECT in SQL Server?
Also if I needed to do something like this for my own work, I wouldn't attempt to do it in a single query.. This would be a pain to maintain and might have memory/performance issues. It would be best have a script traverse the table row by row, update on a single row in a transaction before moving on to the next row. Much slower, but simpler to understand and possibly lighter on your database.