Is the following possible, i been racking my brain to think of a solution.
I have an sql table, very simple table, few text columns and two int columns.
What i want to ideally do is allow user to add a row, but just the text columns and have the sql automatically put the numbers in the integer columns.
Ideally id like these numbers to random but not already exsist (so every row has a unique number) in the column. Also 10 digits long (but think that might be pushing it).
Is there anyway i can achieve this within the query itself?
Thanks
Sure - you pass the string as parameters to the Insert statement and the values as well - after you computed them. you can use SQL fucntion to generate the random number, or use the code you're calling from to generate them.
You can generate unique int numbers for a row with setting it AUTO_INCREMENT. However if you want something like a random hash, you need to do it in your backend. (or in a stored procedure)
Just a thought: if you generate long enough random strings you don't need to worry about having duplication usually. So it's safe to generate a random string, try to insert it and repeat until you get a duplicate entry error. Won't happen most of the time so it might be quicker than checking it first with a select.
You can generate a random number using MySQL. This will generate a random number between 0 and 10.000:
FLOOR(RAND() * 10001)
If you really want the numbers to always be 10 digits long you can generate a number between 1.000.000.000 and 9.999.999.999 like this:
FLOOR(RAND() * 9000000000) + 1000000000
The chance of the number not being unique is ~0.0000000001% and rising as you insert new rows. For a 0% chance of collision I'd suggest doing this the right way and handling this in code and not the database.
The random function explained:
What is happening is RAND() is generating a random decimal number between 0 and 1 (never actually 1). Then we multiply that number by the maximum number that we wish to produce plus 1. We add 1 because the biggest number produced for a set maximum number of 10 will be 9,XXXX and never actually 10 or above (remember I said that RAND() never generates 1), so we add plus one to produce the possibility of 10,XXXX which we later floor using FLOOR() to produce 10. In this case though we don't add 1 because 10.000.000.000 will become possible and it breaches our 10 digit boundary. Then we add the minimum number which we want produced (+ 1.000.000.000 in this case) while subtracting the same from the number we entered before (the maximum number).
Related
I need 10 random ids at time. I need to get a new set of random ids every time I ask for a new set, but the new ones must not include any of the ones I already got from any number of previous times I asked for a new set Unless the process is reset. I may have a total of 100 or 1million ids in my database. I plan to use the ids to show 10 items on a webpage, with next and previous buttons. The pages already shown have to be consistent with the original items shown if the users goes back to any previously shown page
I have an idea that I select random numbers with seed 1000 times ,store it on redis server and pop out every 10 rows when a user enter the page. Are there any different ideas?
For a large set of non-repeating 'random' numbers you are probably better off using encryption. If numbers do not repeat, then they are not truly random because they are constrained not to repeat. Every time you pick a number the pool of available numbers shrinks. Hence the output is not truly random.
To implement, set up a counter: 0, 1, 2, 3, ... Pick a constant key. Then encrypt the counter using the key to get a non-repeating output. Then increment the counter ready to generate the next output. Because encryption is reversible then different inputs using the same key are guaranteed to give different outputs. Encryption is a one-to-one process.
AES will give you 128 non-repeating bits, DES only goes to 64 bits. If 128 bits are not enough then you will have to do some research on larger block ciphers, such as Rijndael.
You are looking for a repeatable random sort. In MySQL, you can do this by passing a seed to mathematical function rand(), as explained in the documentation:
for equal argument values, RAND(N) returns the same value each time, and thus produces a repeatable sequence of column values.
This gives you the first 10 records:
select t.*
from mytable t
order by rand(12345)
limit 10
You can then paginate; to get the "next" 10 records, you use the same seed to rand(), and offset the result:
select t.*
from mytable t
order by rand(12345)
limit 10 offset 10
I am very surprised that I can't figure this out.
I'm currently outputting a table from MySQL in a somewhat random order. I say somewhat because there is a formula that is partially reliant on RAND(). In any case, we can assume the order is effectively random for my question.
This was all working great, except I want to keep the same order for a "session". I don't want it to keep jumping around while actively using the data. I have been trying to figure out how to have MySQL generate the same sequence a second time.
I know that you can do RAND(N) where N is a seed, but as far as I can tell that will be the exact same number each time. So basically there will be no random factor at all if I use that.
What I would like is a way I can feed a seed into my ORDER BY and always get a reliable output order. For the same seed, I will get the same order, and if I feed in a different seed, it will be a different random order.
The best I could come up with is that I could create an additional table cell with a RAND for each row and use that for sorting. There are a few issues:
Additional memory is used in the database.
It doesn't work for multiple users, because I'd need a separate column for each user.
I have to think about this, but I'm pretty certain that there is a clever solution here that doesn't involve me adding an additional column to the database. Has anyone else ever encountered the need to do something like this?
As you mentioned, you can provide a seed to generate a sequence of random numbers. The algorithm for generating random numbers returns the same sequence of numbers for the same seed number. For example;
SELECT Rand(1) AS rnd, CustomerId, CustomerName FROM Customers ORDER BY rnd
By doing so you, you will always have the same random order for the seed "1". You can provide session Id or some similar number in order to get the same result.
Hope it helps.
I would strongly suggest that you use one of the columns to generate the number:
select t.*
from t
order by rand(t.id);
This assumes that id is an integer. You can get a different ordering by adjusting the seed, say, rand(t.id + 1).
I am wanting MYSQL to assign a 16 digit number for each entry as it will be used for a private credit card service. How do I do this??
I had set the field which is called id to auto-increment and bigint but it still only assigns the numbers in order starting with 1.
I am needing the numbers to be 16 digits long and random.
Please help!
You can set the auto increment number to start at any number
ALTER TABLE MY_TABLE AUTO_INCREMENT = 1000000000000000; -- the first 16-digit number
The only restriction on the number specified is that it be not less than the current maximum number for the auto increment column for the specified table.
This however will not provide random numbers.
To create a random 16 digit number, you could use a trigger on insert that uses PASSWORD() function, which creates a 16-digit hexadecimal number, and convert it to a number if you need by calling UNHEX() and SUBSTR() on the result to capture 16 random digits.
For security, you should pass a seed with a value, eg the new id value concatenated with another piece of info from the record concatenated with a constant concatenated with perhaps the current time. It's up to you how far you want to go.
The random number could be done in your application code too, whcih may be a better option as it's easier to debug and control than database kung fu.
I'm trying to figure out how to make a scope that will return random ActiveRecords while also supporting will_paginate.
Right now each page view gets a completely different random set of ActiveRecords. Thus each pagination link, is actually just another random set of records.
How might I set up a scope so that it will be a random order that persists through pagination?
I'm guessing that I need to have some sort of seed that is based on time?
I'm guessing that you're using ORDER BY RAND() in your SQL to get your random ordering. If you are, then you can provide a seed for the random number generator:
RAND(), RAND(N)
[...] If a constant integer argument N is specified, it is used as the seed value, which produces a repeatable sequence of column values.
So you just need to pick a seed (possibly even by using seed = rand(1e6) or something similar in your Ruby code) and track that seed in the session. Then, for the next page, pull the seed out of the session and feed it to MySQL's RAND function.
Keep in mind that ORDER BY RAND() (with or without a seed) isn't the cheapest operation on the planet. If your searchable table is small, you could generate a table with a bunch of columns, fill it with random numbers (probably generated by RAND), and join that table in to provide your random sequence to order by. You would provide different sequences to different viewers by choosing different columns from the random number table: for one user you sort by column 11 of the random number table/matrix but another user will use column 23. Keep in mind that tables (with a primary key) really are just functions on a finite domain (and vice versa) so which you choose is often just an implementation detail. Implementing RAND using a table will usually be pretty cumbersome but I thought I'd mention the option anyway.
I want to pick a random number from a database say 1, when I query again say 10 times I'm querying it should return all different random numbers.
Use ORDER BY RAND()
If you want to get just one random record, your query should look like:
SELECT * FROM table ORDER BY RAND() LIMIT 1
If you only want a random number, don't use a database, use a random number generator. If you don't want repeats, simply keep track of the random numbers you've seen before and, if you pick one again, increment the new number by one until you reach a number you haven't seen yet.
If you want, say 10, random records from the database, then use #sAc's solution, but get them all at the same time. That will ensure that you don't have repeats in your selection. If you must select them one at a time, use the same technique as for the random number and keep track of the records you've seen before. Don't use the LIMIT directive, but simply select the first record you haven't seen on each iteration.