MS Access Automatically Generate Random Number - ms-access

I want to generate a 6-digit random number in a table row in MS Access, is it possible?
I've tried to make a random number for a user's unique ID in a table, but sometimes it generates a negative number like -43543435.

You can create random numbers between limits with this:
Int((maxlimit - minlimit + 1) * Rnd + minlimit)
In your case, you want a 6 digit number, so:
minlimit = 100000
and
maxlimit = 999999
So:
Int(900000 * Rnd + 100000)
You can find more about the function Rnd here:
https://support.office.com/en-us/article/rnd-function-503cd2e4-3949-413f-980a-ed8fb35c1d80

sometimes it generates a negative number like -43543435
That's by design. A random autonumber can take any value within the range of a Long.
It should make no difference to you, as the value of the ID in any case should be meaningless as its only purpose is to identify the record uniquely and doesn't have to be displayed for the user.
If you wish to apply random numbers to the records for the purpose of sorting, you can study the methods in my article:
Random Rows in Microsoft Access
If you don't have an account, browse to the link: Read the full article.

Related

Is possible to remove duplicates in Power BI based on a time interval between the data?

I have a list of leads data.
The table has a lot of infos like date, name, email, mobile number, etc.
However, some of these leads are duplicates: the same person generated more than one lead
What i want to do is to remove the duplicate leads.
The problem is, to be considered a duplicated lead, the email or the mobile number must appear in more than one row, in a time interval of 30 days.
And only those who come next must be considered duplicated. The first one is always a not duplicated lead.
E.g.
1) If Jones generated a lead in 01/01/20 with his email abc#abc.com and then generate another lead 10 days after, in 10/01/20. The first lead is a single lead (not duplicated) and this second lead must be considered duplicate.
2) If Maria generated a lead in 01/01/20 with her email xyz#abc.com and then generate another lead 40 days after, in 10/02/20. The first lead is a single lead (not duplicated) and this second lead also must be considered single (or not duplicate).
To mark the lead as duplicate or not, i want to generate a new column with the time between the last lead of the same person (same email or same mobile number)
Then generate a new column with the label "Duplicate" or "Not Duplicate" based on the time showed on the last column. If its > than 30 days, that is a single lead. Otherwise (<30 days) is a duplicate lead.
E.g picture:
Can someone please help me on how to do that?
Getting the lag/lead data is not very straight forward in Power BI. You will have to use a combination of EARLIERand some aggregate function to get the specific result. For your specific scenario, the following calculation might work:
Day Difference =
VAR name1 = 'Table'[Name]
VAR Lastdate1 = MAXX(FILTER('Table','Table'[Name]=name1 && 'Table'[date]<EARLIER('Table'[date])),'Table'[date])
RETURN
IF(
DATEDIFF(Lastdate1,'Table'[date],DAY)=BLANK(),
100,
DATEDIFF(Lastdate1,'Table'[date],DAY))
Once the column is created, you can filter for all records <=30 to get the result you are looking for. I have replaced the blanks with 100, so that the original records don't get removed when applying the condition.
If you are looking for the "Tag" value, then the following calculation will get you the tag values directly:
Tag =
VAR name1 = 'Table'[Name]
VAR Lastdate1 = MAXX(FILTER('Table','Table'[Name]=name1 && 'Table'[date]<EARLIER('Table'[date])),'Table'[date])
RETURN
IF(IF(
DATEDIFF(Lastdate1,'Table'[date],DAY)=BLANK(),
100,
DATEDIFF(Lastdate1,'Table'[date],DAY))<=30,"Duplicate","Single")

Access 2013 Count

I am working on a report in Access 2013 I need to seperate the first 20 records in a column that contain a value and assign a name to them. Such as at 1-20 I need it to insert Lot 1 at 21-40 need to assign Lot 2 etc... The report needs to be separated by lots of 20. I can also just insert a line when it reaches sets of 20 without a name if that makes it easier. Just need something to show a break at sets of 20.
Example: As you can see the report is separated by welder stencil. When the count in the VT column reaches 20 I need to enter a line or some type of divider to separate data. What our client is asking for is we separate the VT in sets of 20. I don't know whats the easiest way to accomplish this. I have researched it but haven't found anything.
Example Report with Divisions
Update the report's RecordSource query by adding "Lot" values for each row. There are multiple ways of doing this, but the easiest will be if your records already have a sequential, continuous numerical key. If they do not have such a key, you can research generating such sequential numbers for your query, but it is beyond the scope of this question and no details about the actual data schema were supplied in the question.
Let's imagine that you have such a key column [Seq]. You use the modulo (mod) and/or integer division operators (\ - backslash) to determine values that are exactly divisible by 20, e.g. ([Seq] - 1) mod 20 == 0.
Generate a lot value for each row. An example SQL snippet: SELECT ("Lot " & (([Seq] - 1) \ 20)) As LotNumber ...
Utilize Access report sorting and grouping features --grouping on the new Lot field-- to print a line and/or label at the start of each group. You can also have the report start a new page at the beginning or end of such a group.
The details about grouping can be found elsewhere in tutorials and Access documentation and are beyond the scope of this question.

Using last number from the first 4 numbers to fetch users details from MySQL

If I have digits like this(account numbers actually).
200101
200201
200201 is for saving account while 200101 is a current account.My main goal is to fetch all details of users with acount that start with 2001 from mysql. How can I manipulate number like this in MySQL to pull out the users details?
If the account number is a string, then use:
where accountnum like '2001%'
If it is a number, then I presume you want to lop off the last two digits. For that, use division:
where floor(accountnum / 100) = 2001
I don't recommend using string functions on numbers and vice versa.

MySQL ORDER BY CASE / IF relevance issue

I've never worked with ORDER BY CASE or ORDER BY IF() and the few examples I've found on the internet are more confusing than helping me trying to accomplish following task:
I have a member list and I want to "reward" the user's activity a bit by ordering a user higher (to the top) in this member list.
In my example, I have a MySQL table called "users" with 3 columns:
user_percentage | user_photo | user_lastlogin
----------------------------------------------------------
12 1 1356389646
42 1 1456549641
37 0 1776389443
84 1 1356535535
56 0 1868689646
66 0 1811189622
71 1 1656779645
"user_percentage" holds the value (0 - 100) of all filled in profile
fields by each user.
"user_photo" holds the value (0 = false , 1 =
true) if a user has upload a profile photo.
"user_lastlogin holds the
value (timestamp) of their last visit.
It's a bit difficult to explain, but to say it simple what I want:
A user with a higher user_percentage value should be on top of the member list, but if he got no user_photo, then he should be "moved down" in the member list, same if he got an old user_lastlogin timestamp, then list him even more down in the member order.
Also what I'm trying to prevent is that a user has signed up, filled in all profile fields (then user_percentage value will be = 100) and uploaded a photo (then user_photo will be = 1), but hasn't login anymore since a long time (so he has a very old user_lastlogin = timestamp), then I want this user moved down in the member list order.
My question is: Is this somehow possible to do with 1 MySQL ORDER BY statement?
Let's say user_photo has just an importance of 30% while user_lastlogin got a higher importance and user_percentage also a bit higher.
Any ideas?
Best regards!
In order to even begin writing the SQL, you need to clarify how much each parameter is worth.
You should produce a list of examples and then convert it into either a simple calculation like:
(photo*timesincelogin*20)+(percentage)
or CASE based statements which each have a calculation - i.e:
ALL people with photos THEN ALL people with out, subsorted by time*percentage.
Hand-wavy 'move down a bit' is not specific enough for an answer with SQL commands.

How do I store orders?

I have an app which has tasks in it and you can reorder them. Now I was woundering how to best store them. Should I have a colomn for the ordernumber and recalculate all of them everytime I change one? Please tell me a version which doesn't require me to update all order numbers since that is very time consuming (from the executions point of view).
This is especially bad if I have to put one that is at the very top of the order and then drag it down to the bottom.
Name (ordernumber)
--
1Example (1)
2Example (2)
3Example (3)
4Example (4)
5Example (5)
--
2Example (1) *
3Example (2) *
4Example (3) *
5Example (4) *
1Example (5) *
*have to be changed in the database
also some tasks may get deleted due to them being done
You may keep orders as literals, and use lexical sort:
1. A
2. Z
Add a task:
1. A
3. L
2. Z
Add more:
1. A
4. B
3. L
2. Z
Move 2 between 1 and 4:
1. A
2. AL
4. B
3. L
etc.
You update only one record at a time: just take an average letter between the first ones that differ: if you put between A and C, you take B, if you put between ALGJ and ALILFG, you take ALH.
Letter next to existing counts as existing concatenated with the one next to Z. I. e. if you need put between ABHDFG and ACSDF, you count it as between ABH and AB(Z+), and write AB(letter 35/2), that is ABP.
If you run out of string length, you may always perform a full reorder.
Update:
You can also keep your data as a linked list.
See the article in my blog on how to do it in MySQL:
Sorting Lists
In a nutshell:
/* This just returns all records in no particular order */
SELECT *
FROM t_list
id parent
------- --------
1 0
2 3
3 4
4 1
/* This returns all records in intended order */
SELECT #r AS _current,
#r := (
SELECT id
FROM t_list
WHERE parent = _current
)
FROM (
SELECT #r := 0
) vars,
t_list
_current id
------- --------
0 1
1 4
4 3
3 2
When moving the items, you'll need to update at most 4 rows.
This seems to be the most efficient way to keep an ordered list that is updated frequently.
Normally I'll add an int or smallint column named something like 'Ordinal' or 'PositionOrdinal' as you suggest, and with the exact caveat you mention — the need to update a potentially significant number of records every time a single record is re-ordered.
The benefit is that given a key for a specific task and a new position for that task, the code to move an item is just two statements:
UPDATE `Tasks` SET Ordinal= Ordinal+1 WHERE Ordinal>=#NewPosition
UPDATE `Tasks` SET Ordinal= #NewPosition WHERE TaskID= #TaskID
There are other suggestions for a doubly linked list or lexical order. Either can be faster, but at the cost of much more complicated code, and the performance will only matter when you have a lot of items in the same group.
Whether performance or code-complexity is more important will depend on your situation. If you have millions of records the extra complexity might worth it. However, I normally prefer the simpler code because users normally only order small lists by hand. If there aren't all that many items in the list the extra updates won't matter. This can typically handle thousands of records without any noticeable impact in performance.
The one thing to keep in mind with your updated example is that the column is only used for sorting and not otherwise shown directly to the user. Thus, when dragging an item from the top to the bottom as shown the only thing you need to change is that one record. It doesn't matter that you'll leave the first position empty. This means there is a small potential to overflow your integer sort with enough re-ordering, but let me say again: users normally only order small lists by hand. I've never heard of this risk actually causing a problem.
Out of your answers I came up with a mixture which goes as follows:
Say we have:
1Example (1)
2Example (2)
3Example (3)
4Example (4)
5Example (5)
Now if I sort something between 4 and 5 it would look like this:
2Example (2)
3Example (3)
4Example (4)
1Example (4.5)
5Example (5)
now again something between 1 and 5
3Example (3)
4Example (4)
1Example (4.5)
2Example (4.75)
5Example (5)
it will always take the half of the difference between the numbers
I hope that works please do correct me ;)
We do it with a Sequence column in the database.
We use sparse numbering (e.g. 10, 20, 30, ...), so we can "insert" one between existing values. If the adjacent rows have consecutive numbers we renumber the minimum number of rows we can.
You could probably use Decimal numbers - take the average of the Sequence numbers for rows adjacent to where you are inserting, then you only have to update the row being "moved"
This is not an easy problem. If you have a low number of sortable elements, I would just reset all of them to their new order.
Otherwise, it seems it would take just as much work or more to "test-and-set" to modify only the records that have changed.
You could delegate this work to the client-side. Have the client maintain old-sort-order and new-sort-order and determine which row[sort-order]'s should be updated - then passes those tuples to the PHP-mySQL interface.
You could enhance this method in the following way (doesn't require floats):
If all sortable elements in a list are initialized to a sort-order according to their position in the list, set the sort-order of every element to something like row[sort-order] = row[sort-order * K] where K is some number > average number of times you expect the list to be reordered. O(N), N=number of elements, but increases insertion capacity by at least N*K with at least K open slots between each exiting pair of elements.
Then if you want to insert an element between two others its as simple as changing its sort-order to be one that is > the lower element and < the upper. If there is no "room" between the elements you can simply reapply the "spread" algorithm (1) presented in the previous paragraph. The larger K is, the less often it will be applied.
The K algorithm would be selectively applied in the PHP script while the choosing of the new sort-order's would be done by the client (Javascript, perhaps).
I'd recommend having an order column in the database. When an object is reordered, swap the order value in the database between the object you reordered and the objects that have the same order value, that way you don't have to reoder the entire set of rows.
hope that makes sense...of course, this depends on your rules for re-ordering.