简体   繁体   中英

Getting the Max rownumber +1 from a database where date = this month

I'm designing a means to have an auto incrementing value for a ticketing system. Its an existing format that in which I'm trying to mirror the original system in order to keep the staff who use the current system happy. Here's an example of their unique identifier:

ID No: 13L041

In this case the 13 represents the year (2013) L represents the month (December) and the 041 represents the ticket number for that month. I've got the code here for getting the short year and assigning a month code here :

<?php
$trackingID ='';
$year = date("y");
$trackingID.= $year;
$month = date("n");

switch($month){
    case 1:
        $monthCode ="A";
        break;
    case 2:
        $monthCode ="B";
        break;
    case 3:
        $monthCode ="C";
        break;
    case 4:
        $monthCode ="D";
        break;
    case 5:
        $monthCode ="E";
        break;
    case 6:
        $monthCode ="F";
        break;
    case 7:
        $monthCode ="G";
        break;
    case 8:
        $monthCode ="H";
        break;
    case 9:
        $monthCode ="I";
        break;
    case 10:
        $monthCode ="J";
        break;
    case 11:
        $monthCode ="K";
        break;
    case 12:
        $monthCode ="L";
        break;
    }
$trackingID.= $monthCode;
$trackingID.= 1;
echo $trackingID;
?>

This code works great but I'm now having trouble as to how to get the incrementing number from the database. Lets assume that there are 70 tickets in the system from this month. From that when a new ticket is entered we'd expect it to have the ticket number 14A71. I've got the code to query SQL to find the row numbers here:

SELECT trackid, @rowNum := @rowNum + 1 AS row_number FROM customerservice.tbl_tickets JOIN (SELECT @rowNum := 0) r;

The end user want the incremental number to reset each month. so January will start at 001 and end at 131 for example then February will start at 001 and so on.

I'm just having issues getting my head round how to get records that have been posted in the current year/month. I could have it performed in the switch statement, assigning the lower and higher values in order to perform a date between but I'd rather have it done automatically by the system. Is there a way This could be done because I'm simply quite clueless and I'm getting all confused about it all. Any help would be appreciated.

Cheers, Dan

Since it sounds like you have a datetime value for record insertion, I would highly suggest using it. Here you can get the most recent ticket for the current month

SELECT trackid
FROM tbl_tickets
WHERE insert_date_field >= MONTH(CONCAT_WS('-',YEAR(NOW()),MONTH(NOW()),'01 00:00:00')
ORDER BY insert_date_field DESC
LIMIT 1

You can easily use string manipulation to get the last part directly in the query if you desire. If the number of rows in the result set is 0, then this would be the first record for the month.

Of course you probably need to look at reading this record and then adding the new record with incremented counter within a transaction and with appropriate table locking so that you don't end up with duplicate values.

If you don't have a date_time field you can try something like this

Select count(*)+1 From customerservice.tbl_tickets Where trackid Like '$year$monthCode%';

we fetch for ones that begins with the combination of year and monthCode.

sure $year and $monthCode are from your php code.

Hope that helps.

Because we have a somewhat limited knowledge of your database schema it's hard to suggest a full proof solution, but bear with me.

I would try to keep the data in the database as normalized as possible, and only modify the fetched data so that the end user is happy (but never alter it in the database). Let's say that this is more or less the proposed structure:

CREATE TABLE some_table (
    date_tracker TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    ticket_count INT UNSIGNED NOT NULL,
    INDEX date_tracker (date_tracker)
)

The date_tracker field will record when an insert was performed (from your comments I deduced that you already have such a field, so use it). The ticket_count field will record the amount of tickets for that month (we will increment it "manually"). I added an index on the date_tracker column, though depending on how many records you have that might not be necessary.

An example insert statement would look something like this:

INSERT INTO some_table
(
    ticket_count
)
SELECT
    COUNT(*) + 1
FROM
    some_table
WHERE
    DATE_FORMAT(date_tracker, '%Y-%c') = DATE_FORMAT(CURDATE(), '%Y-%c')

Of course you will most probably insert more information, but this is mainly to get you on the right track. As you see, I store the ticket_count for the given year and month in an INT column, and I increment it by selecting the previous count + 1.

Now comes the interesting partL - the select statement:

SELECT
    CONCAT(
        DATE_FORMAT(date_tracker, '%y'),
        CHAR(DATE_FORMAT(date_tracker, '%c') + 64),
        ticket_count
    ) AS ticketid
FROM
    some_table
LIMIT 0, 30

The CONCAT() function simply concatenates all its arguments using an empty string. The call to the DATE_FORMAT function returns the 2 digit representation of the year (14 for 2014, 93 for 1993 etc.). The CHAR function returns the resulting character using ASCII character mapping, notice how I have taken the month number and added 64 (thus, for January it will be CHAR(1 + 64) = CHAR(65) = A, which is what you were doing "manually" in your switch). The ticket count is simply that ticket's ticket number for that year and month.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM