How to sort numbers containing current year in prefix - php

I am having trouble sorting the job numbers in my project.
My client requirement is to store the job numbers in the below format:-
current year-1, current year-2, current year-3, and so on...
For example:-
The current year is 2021 so the job number will be like this:-
21-1, 21-2, 21-3, 21-4, and so on...
When the year changes it should start again from 1 and so on for the next year.
For example:-
22-1, 22-2, 22-3, 22-4, and so on...
I had stored the job numbers in the above format successfully but I am unable to sort the job numbers in the correct way as required by the client.
I had sorted the data in this way:-
21-1, 21-10, 21-100 to 21-109, 21-11 to 21-19, 21-2 and so on...
but the actual sort should be like this:-
21-1, 21-2, 21-3, 21-4...21-10, 21-11 to 21-99, 21-100 to 21-199 and so on...
And if the year changes then:-
22-1, 22-2, 22-3, 22-4...22-10, 22-11 to 22-99, 22-100 to 22-199 and so on...
I hope I have explained my problem briefly. Please help me in sorting out the job numbers.

I assume you need the sorting to occur in your database because you're paging or just otherwise not holding all results in application memory, use use the following sql order by clause:
select my_column
from my_table
order by left(my_column, 2),
len(my_column),
right(my_column, len(my_column) - 2)
Explanation:
left(my_column, 2), numerically sort first two digits so years are grouped together.
len(my_column) group record sequence based on magnitude (i.e., xx-100 appears after xx-2 because it's longer).
right(my_column, len(my_column) - 2) numerically sort record sequence.
Hint: This assumes your year-code is always exactly two digits. I could have found the index of the dash instead, but that feels even more presumptive.
If you require an application-side (PHP) solution, you can use natsort. From W3Schools:
Definition and Usage
The natsort() function sorts an array by using a
"natural order" algorithm. The values keep their original keys.
In a natural algorithm, the number 2 is less than the number 10. In
computer sorting, 10 is less than 2, because the first number in "10"
is less than 2.
Syntax
natsort(array)

21-1, 21-10, 21-100, 1, 10, 100
These are your ids from the database. At first, declare an empty array and a variable for serial then loop through the objects. Push every object with two new keys array["date_serial"], array["serial"]. Then take the new array and then display the result by sorting the array by "serial" key or asc or desc order.

Related

How to display the column value descending when the column having spacial characters in mysql

How to display the column desc order when the column having spacial chars in mysql
I am using the follow query but not display correctly
SELECT quotation_pno FROM crm_quotation order by quotation_pno desc
My output coming like this
quotation_pno
PT/17/999
PT/17/1533
PT/17/1532
PT/16/1531
I want my output like this
quotation_pno
PT/17/1533
PT/17/1532
PT/17/999
PT/16/1531
Please help me
I'd argue, that the output is correct, but your assumptions are not. It looks to me, as if quotation_pno is some kind of textual column, right?
The sorting assumes, that you want to sort text and this works this way:
Set i to 0
Compare the i-th character of two strigns
If they are the same and the end is not reached, increase i by 1 and proceed with step 2
Otherwise order the two strings according to the value at the i-th position
(There are some things elided and the pseudocode is boiled down to the very basic, needed to understand the principle).
Applied to your example this means, when the comparison compares PT/17/999 and PT/17/1533 it looks at the characters 0 to 5 and "sees" that they are equal. When it compares the characters at position 6, they are '9' and '1'. Since the character '9' is considered to be greater than '1', PT/17/999 is placed before PT/17/1533.
How to solve the issue?
There are some ways coming into my mind, that will allow you to achieve the desired sort order.
First, you could prepend the numbers with zeros. This will allow you to re-use most of your existing structure, but will result either in very many zeros, or a system that is somehow limited, since you will be restricted to the number of digits you decided to use (or the sort will fail again).
The second possibility is, to store the parts in (additional) numerical columns in the table, e.g. one for year and one for the order number in this year. This is the more flexible approach, but involves more changes.

Generating unique fixed integer ids from array of ids

So here is the situation... I got array of objects, each marked with unique integer id, and for each and every combination of those objects, I need to create new ones, each with unique ids. Problem is that that list of objects is dynamic, used in stateless environment, so newly generated ids must be same for every run.
To make it clearer what I need here, consider that array of objects as array of their ids, for example: [10, 7, 23]. And basically, I need to get ids for all the possible combinations:
10, 7
10, 23
7, 23
10, 7, 23
What's important here is that generated ids must be same for each distinct combination (for example: 10 and 7 should always produce same id). Also, newly added objects should not affect previously generated ids. So for example, when some new object is later on added to that list, ids generated from previous combinations must remain the same as before new object was added.
Currently, I have a solution that pretty much comes down to generating new id as a result of the sum of combining ids, so resulting ids are:
17
33
30
40
Of course, this approach can produce duplicate ids, and that's the reason I'm asking for advice for some more sophisticated algorithm. I also tried introducing fixed offset of 1000 for newly generated ids and multiplying sum with number of objects in combination, so that for example resulting ids are 1034 (1000+(10+7)*2), 1066 (1000+(10+23)*2), etc., but I'm not sure that it would save me from duplicates. :)
Clear mention, I need this for the purpose of certain PHP project, but as this problem is not language-specific, I hope that there are some good mathematicians that can bring some good solution. :)
Useful information is fact that combining ids are in range from 10000-99999 and maximum number of items in combination does not exceed 10.
Please note that I do not need solution for how to make all the combinations from array elements, but only that "formula" for producing integer id.
Thanks in advance.
Not really sure what your aim is, but I'll have a go...
Have you tried using character keys? For example 10, 7, 3 becomes a sequence with an underscore. Each sequence will have a unique hash.
$arrayOfKeys = array(10, 7, 3);
$hash = implode('_', $arrayOfKeys);
print $hash;
# 10_7_3
Personally I'd go for this simple approach. If you're using a database and you're not producing, say, 100k records per day, it should be pretty fast using an indexed (primary key or unique) varchar field.
If you are to create numbers, here a tip: take the length of the largest number and that will be the prefix of your sequence, e.g.:
10, 5, 1 -> 2100501
105, 45, 201 -> 3105045201
The prefix will tell you what the length of the following sequences are. I can't think of any way you'd get doubles... Anyone? ;)
Hope it helps...
Step 1: Sort the values you get.
eg: if you get 10, 7 or 7, 10 it should result result in 7, 10 before going to the ID generator. If you know the range of your numbers i.e lets assume [0-100] use radix or count sort, will be fast.
Step 2 : Represent the numbers as strings, seperated by any chosen seperator.(':') maybe.
eg: for 7, 10 id will become "7:10".
Sorting is being done to avoid generating different ID's for 10, 7 and 7, 10.
BTW What do these numbers represent?
I don't think this is possible unless you allow labels of increasing length.
Assume you have a maximum of N distinct objects, corresponding to N distinct labels.
If you want to be able to represent all possible pairs, assuming order in a pair does not matter, you potentially need N.(N-1)/2 extra labels, whatever they are, and you need to reserve them all.
And for all triples, N.(N-1).(N-2)/6, for all quads N.(N-1).(N-2).(N-3)/24...
This grows exponentially and will very quickly exceed the capacity of integers.
Any other solution that tries to compress the space of labels, such as hashing, will result in collisions. You can resolve the collisions by maintaining collision table, but this will break the "generated ids must be same for every run" requirement.

How to use sortable data structure in redis

How to store and retrieve data-structure like this in redis in most efficient way. The record will be accessed by username value which will be unique and we need to sort data by date and counter values.
Also, is redis the best choice for this scenario (performance takes precedence here over everything).
Sorted sets sort items automatically based on a score value, which can be any string-based value for double precision floating point number. You can also use SORT command which does on-the-fly sorting for lists and sets.
Going back to sorted sets, you can sort by date using using long timestamps:
ZADD uniqueName 13733654484 stringData1 197625203673 stringData2
Or you can sort by counter:
ZADD uniqueName 100 stringData1 101 stringData2
That's one way to do it.

Solr: calculating the difference between two given dates when one of the values is *

I'm working on something that when a range filter is active, the range facets will update accordingly. If no filter is given, I'm using a default range & gap. If a filter is set I do a second solr call to recalculate the facet range gap.
So for example at first I show range facets of a gap of 10YEARS. When you filter one of those, it shows 10 range facets of 1YEAR. If you filter again, it'll show 12 buckets with a 1 month range etc...
It kind of works, but I'm having trouble when the range filter includes a *. Solr knows how to correctly filter results when solrfield:[1960-01-01T00:00:00Z TO *] is given, but I don't know how I recalculate the date range facet gaps based on *. Right now I calculate the difference between the two dates as a unix timestamp and calculate the range gap based on that.
Also, is there a name for what I'm trying to do here? I'd call it 'variable range gaps', but I'm not sure if that's correct.
I'm not even sure if what I'm doing is the best approach. Any advice is welcome.
Edit: what my question comes down to is: I would like to calculate difference (as unix timestamp) between the highest and lowest date of a field in every solr query.
Edit 2: Every solr call I do takes about 300ms (on a relatively small index). That's quite a bit in case I do 2 extra calls with a date sort to find the highest and lowest date value in the query. Then performing the 4th solr call with the correct date gap (and from/to values), would get a bit slow.
You can probably turn it into familiar "limited date range" case. If it is impossible for your data to have datetime set in the future, your can replace * with NOW always receiving the same resultset (as no date can be later than current moment) and calculate gaps basing on current timestamp.

PHP: Compare two sets of numbers, no dupes

I'm creating a lottery contest for my site, and I need to know the easiest way to compare numbers, so that no two people can choose the same numbers. It's 7 sets of numbers, each number is a number between 1 and 30.
For example, if user 1 chooses: 1, 7, 9, 17, 22, 25, 29 how can I make sure that user 2 can't choose those same exact number?
I was thinking about throwing all 7 numbers into an array, sort it so the numbers are in order, then join them into one string. Then when another user chooses their 7 numbers, it does the same, then compares the two. Is there a better way of doing it?
What you describe sounds like the best way to me, IF you are dealing with all submissions in the same script - I would trim(implode(',',$array)) the sorted array, store the resulting string in an array and call in_array() to determine whether the value already exists.
HOWEVER I suspect that what you are actually doing is storing the selections in a database table and comparing later submissions against this table. In this case (I am taking a liberty and assuming MySQL here but I would say it is the most common engine used with PHP) you should create a table with 7 columns choice_1, choice_2 ... choice_7(along with whatever other columns you want) and create a unique index across all seven choice_* columns. This means that when you try and insert a duplicate row, the query will fail. This lets MySQL do all the work for you.
Try array_diff. There are some really good examples on php.net.

Categories