Mysql auto-increment partially by today's date only - is this possible? - mysql

I have a requirement to auto increment an integer which I need "for the day". This is used for box numbers for orders being sent out in a day through our client's e-commerce website.
For example, the first order today would contain the box number 01. The second order would contain 02. This would be incremented specifically by a trigger or some kind of automatic function, depending on the date.
What I have described is not my exact/full requirement but I would like to know how I can code the above in particular? So if we imagine a table like this:
myboxnumbers (boxid [auto increment], yyyymmdd-date, boxno)
I would like a function in Mysql (stored procedure) to 'give me the next increment of the box number for today').
E.g.
function generateBoxNoForToday() {
//1. Get today's date
//2. Check the latest boxno in the above table for today
//3. If no boxno yet for today, set $new-boxno = 1
//4. If there is a boxno, my new $new-boxno = boxno + 1
//5. INSERT INTO myboxnumbers (yyyymmdd-date, boxno) VALUES (today(), $new-boxno)
}
Please guide on how could I actually "do" this in Mysql? I suppose I'm too used to PHP so it's tempting to do it there :) but it makes sense that this is purely a database function and so I would like to do how to do this and the easiest route to take for such a function?
Many thanks!

It's not hard to put this into your insert statement for this table. As #AlmaDo pointed out, you need to lock the table and avoid the COUNT(*) operator, however.
Issue these three sql statements one after the other. Don't do anything else until you've issued all three, or your system may fail to scale up when you need it to.
LOCK TABLES myboxnumbers WRITE;
INSERT INTO myboxnumbers
(yymmdd_date, boxno)
VALUES
(TODAY(),
SELECT 1 + IFNULL(MAX(boxno),0)
FROM boxnumbers
WHERE yymmdd_date = TODAY()
);
UNLOCK TABLES;
To make this efficient, you need an index on (yymmdd_date,boxno).
To retrieve the just-inserted boxno value, you can do this immediately after your UNLOCK TABLES statement.
SELECT boxno FROM myboxnumbers WHERE boxid = LAST_INSERT_ID()

Related

How can I increment a field value by 1 using SQL Query in MS Access

I'm working on a project using Automation Anywhere Client.
I'm extracting data from MS Excel to MS Access using SELECT and UPDATE statements, but it is possible that the data could repeat itself, and in this case, I would like to UPDATE only 3 fields, those are the statements that I'm using
INSERT INTO $vDiagnosis$
VALUES ('$vID$','$vFirstName$','$vLastName$','$vGender$','$vPhone$','$vAge$',
'$vDateOfVisit$','$vCondition$','$vInsuranceCo$','$vInsuranceNr$','$vVisitingNumber$')
Update $vDiagnosis$
SET DateOfVisit = '$vDateOfVisit$', Condition = '$vCondition$'
WHERE ID = '$vID$'
which are the DateOfVisit and the Condition and the VisitingNumber (which is the number of times someone visited that hospital). The thing is, I'm trying to increment the VisitingNumber every time the UPDATE statement is executed, for example, someone visits today, I want it to be 1, the UPDATE statement is executed again, I want that 1 to increment.
I tried making a variable, and to increment it every time the UPDATE is being executed but whenever it loops and goes to the next INSERT statement, it continues incrementing, even if it inserts a new value.
A preview of the work I'm trying to do on Automation Anywhere
Any help would be appreciated.
Thanks in advance!
Not sure about the variable aspect mentioned, but bumping the VisitingNumber count should be able to be done as:
UPDATE $vDiagnosis$
SET DateOfVisit = '$vDateOfVisit$',
Condition = '$vCondition$',
VisitingNumber = VisitingNumber + 1
WHERE ID = '$vID$'
To the insert, the value for the visitingNumber could simply be 1 without a variable, like so:
INSERT INTO $vDiagnosis$
VALUES ('$vID$','$vFirstName$','$vLastName$','$vGender$','$vPhone$','$vAge$',
'$vDateOfVisit$','$vCondition$','$vInsuranceCo$','$vInsuranceNr$', 1)
Or better, perhaps a default value of 1 could be specified at the table level, and then it would not need to be included with the insert query at all. (it would be set to 1 at insert)
Hope that makes sense.

SQL/mysql - how to display two columns with different value from 1 table

I am trying to make a query for approval of documents, where the result display the name and signature with date. How can I get the date for two people approving the document?
Select Uname
case when stepcode=1 then 'approver1' end as 'name of person'
case when stepcode=1 then 'approver1' end as ' date of signed noted'
case when stepcode=2 then 'approver2' end as 'date of signed approved'
from table
I tried this, but only one result showed up. Only the name, signature and date of the first approval displayed.
We can only answer this by making some assumptions:
the field stepcode denotes what stage of the sign off process the record is at
value of 1 means noted and value 2 means approved. A value of 0 means nothing has happened yet
approver1 and approver 2 are NULL if the action has not yet taken place
If all of the above is true, then there should be no requirement to have a CASE statement for the fields... just including the fields within the SELECT statement will bring the values through if they have been completed.
Some validation of data might be required here though if you are not getting the results you are expecting. Running some rough counts for each of the steps and for where they have values in the approver fields would help to make sure your code is working. The following should give you something to work with:
SELECT
stepcode
COUNT(TableID) AS NumberAtStep
FROM table
GROUP BY stepcode
Using these counts, you can then run your statement without the CASE statements and run a manual count to ensure you are seeing the right number of records with the relevant populated columns for each step.
Further information will be required to delve into your problem further however

SQL - How to select/delete rows with the max value depending on two others

I'm an intern in a property rental company. I'm in charge of developping the CRM under Symfony.
So, ones of my entities are properties (houses) and their availabilities. See the table structure below.
The problem I'm facing for now, is that the availabilities had been defined for each day (e.g. 28/01, 29/01, 30/01) instead of being defined for a range of day (e.g. 28/01 -> 30/01). So, the table is really heavy (~710 000 rows). Furthermore, before we changed the way of editing an availability, it created a new row for a same date instead of editing it. So, there are a lot of duplications in this table.
What I want, is to lighten the DB by keeping only the rows which have the max value in date_modif_availabilities for the same date_availabilities and id_properties.
For example, if I have these rows (availabilities_duplications):
I only want to keep the row with the latest modif like this (availabilities_keep_max_value) :
The thing is, I don't know enough the SQL language. I'm able to write few basics scripts but not complex subqueries. Even with code samples that I found.
Thank you in advance for your help.
You could select the elements for which no element with greater modified date exists.
Something like this:
SELECT avl1.*
FROM availabilities avl1
WHERE NOT EXISTS (SELECT *
FROM availabilities avl2
WHERE avl1.date_availabilities = avl2.date_availabilities
AND avl1.id_properties = avl2.id_properties
AND avl2.date_modif_availabilities > avl1.date_modif_availabilities);
This of course has the pre-condition that the combination of the three columns date_availabilities, id_properties and date_modif_availabilities is unique.
Furthermore, it seems that all columns (except the PK) may be NULL. Looks kinda odd to me.
You can use subquery :
select t.*
from table t
where id_availabilities = (select t1.id_availabilities
from table t1
where t1.id_properties = t.id_properties and
t1.date_availabilities = t.date_availabilities
order by t1.date_modif_availabilities desc
limit 1
);
However, if you have concern about the performance, then you want index on (id_properties, date_availabilities and id_availabilities).

How use parameters in Loop Activity in IBM Datastage?

I'm in this situation: i have a table of certain data with month associate.
I want load another table with the data of current month and the previous 'n'(i want to insert n).
For example: We are in July(7) and insert 3 as 'n' . the job must be load July-June and May.
It's possible set in Loop activity these parameters?
Such as: FROM: , STEP:-1 , TO: - n (but this form doesn't work)
Or there are other solutions?
Thanks
A loop is not necessary at all - from what I understand - you want to dynamically select the time range from one table to write it to anotherone. The probably easiest way is to use a flexible WHERE Conditrion in the SELECT statement. The WHERE condition or parts of it can be a parameter.
An example could be:
SELECT <whatevercolumns>
FROM <sourcetable>
WHERE date > month(current date) - #NumMonths# months
alternatively
SELECT <whatevercolumns>
FROM <sourcetable>
#WHERE#
And you specify the whole WHERE condition in the parameter.

Mysql select part of field and return full value

Good day all,
I have a field called mCodes which has the exact length (7) throughout the table but with different values i.e. a few records with 5036100, 5036102, 5036103, 7010100, 7010101 etc.
I am using a select statement to first search for the first 4 characters i.e 5036 which will return all the records with 5036 just fine
I now need to return the actual full value of the records 5036100 etc. without recreating another sql statement. My statement I am using is as follow -
SELECT LEFT(MCODE, 4), MAKE, MODEL, NEWPRICE23 FROM mautogd1015 WHERE LEFT(MCODE, 4) = '5036'
I have racked my brain over this for a few hours now, any help will be appreciated.
Try something like this.
SELECT MCODE, MAKE, MODEL, NEWPRICE23 FROM mautogd1015 WHERE LEFT(MCODE, 4) = '5036'