mysql sql weird issue? - mysql

return multiple data
why?
mysql sql :
select * from t_book where id=(select round(max(id)*rand()) from t_book)

As suggested by #Tarek you might have duplicated id values. To find out which you can run this query:
SELECT id, COUNT(*) c FROM t_book GROUP BY id HAVING c > 1;

On the assumption that "id" is a unique primary key value, it shouldnt return multiple values. In the returned values do all of the "id" fields match, or is it returning multiple varying ids?

You have a Syntax error,
The function Round takes the form:
ROUND(N,[D]);

The problem is not with your id column's uniqueness.
select round(max(id)*rand()) from t_book
This will return various number of ids, at least in mysql 5.6. I don't know why, but it's really weird.
You can try this, for selecting a random record from your table:
select * from t_book order by rand() limit 1;
If you stick with this round-max-random method, keep in mind that round can return 0 too and it's unlikely that you have a 0 id.
First I thought this is caused by duplicate id values. You can try this fiddle, and see what happens: http://sqlfiddle.com/#!9/7fc510/1.
For multiple runs I got 0, 1 or 2 result records.

Related

MySQL "GROUP BY" experiment

I am testing SQL and I am stuck on one query. It is a useless query but I want to understand it.
select count(*), floor(rand()*2) as x from table_name group by x;
The result is either two rows, or duplicate entry '0/1' for key 'group_key'
What happens that leads to this error?
rand() is going to generate a random number for every row in your table. You are then grouping by the results of all of those random numbers. You will get one row for each unique value.
The main point here is not to group by some strange sinthetic data.
Better to group by some certain fields.
Because mysql have some bugs there.
Like this
http://bugs.mysql.com/bug.php?id=58081
Or this
https://bugs.mysql.com/bug.php?id=60808
Certainly it is trying to create a unique index on a tmp table and that is somehow not working

Trying to avoid duplicate SQL entries

I am trying to avoid adding a certain game's data to my table more than once so I am trying to make an if statement that would check if that game's ID is already in the table, however for some reason the if statement is always false. This is my code:
$a = $_GET['id'];
$colname = $_GET['colname'];
$b = "SELECT count(*)
FROM table
WHERE gameid = ".$a;
if($dup = mysqli_query($dbc, $b)){
if(mysqli_num_rows($dup)==0){
$insrt = "INSERT INTO table ($colname)
VALUES ($a)";
mysqli_query($dbc, $insrt);
}
}
If I were you, instead of using logic within your program to avoid creating duplicate entries, I would simply tell MySQL that your ID column should be unique. Take a look at the info on column definitions in the MySQL Reference Manual, specifically the keywords UNIQUE or PRIMARY KEY.
If you specify that your ID column should be a unique index, then MySQL will prevent another entry with the same ID value from being added. That way, in your program, you can simply attempt to add the data, and the procedure will automatically fail if it is a duplicate. As an added bonus, this means you'll only have to do one query from your program instead of two.
A SELECT COUNT().... query, barring exceptional circumstances, is generally going to return at least one row (more if there is a GROUP BY clause that would indicate otherwise); you need to check that the field value is 0, not that there are no rows in the result.
Change your query to remove the aggregate, and just return a column, e.g.
SELECT gameid
FROM table
WHERE gameid = ?
LIMIT 1
You don't need a count of rows, you just need to know whether a row is returned.
Or, you could add a HAVING clause to your query to not return a row when the COUNT is zero...
SELECT COUNT(*)
FROM table
WHERE gameid = ?
HAVING COUNT(*) > 0
There's no need for you to retrieve the value of the column from the row that's returned, just return an empty resultset, and test whether the resultset is empty, like your code is doing.

Why is "LIMIT 0" even allowed in MySQL SELECT statements?

Limit 0, 1000 returns the first 1,000 results, but LIMIT 0 returns 0 results.
That's not very intuitive imho. For example, dumb old me thought that removing the 1000 would remove the upper limit to the SELECT query, thus returning all of the results.
Why would anybody even want to query MySQL for 0 results?
From the MySQL documentation
LIMIT 0 quickly returns an empty set. This can be useful for checking the validity of a query. When using one of the MySQL APIs, it can also be employed for obtaining the types of the result columns.
limit 0 can be used to get the same columns types of other tables
create table newtable
select col1 from table1 limit 0;
That way, a hard-coded description of the columns types for newtable is not needed, ensuring that the columns types will still match even if a change occurs in the description of table1 before creating newtable
It also works with a more complete statement, involving indexes, engine, multiple tables, etc
create table newtable (primary key (col1)) engine=memory
select col1,col2,col3 from table1,table2 limit 0;
*Polite corrections are welcomed and appreciated if I am incorrect here, but:
My understanding is that LIMIT 0, 1000 is telling SQL that you want to start with the first set of 1000 results in a given database, for the given criteria. For example, if there are 10,000 resulting rows in a dataset, LIMIT 0, 1000 would show you the first set of 1000 results. The zero is like the index of an array in JavaScript - the code starts ITS count with zero, rather than one, when referencing an array item. So item #1 is actually item #0, item #2 is actually item #1, and so on.
In addition to the answers already given, it is also useful when you want to make operations to a table based on the number of rows present in that table.
I.e. using PHP, if you want to delete all entries except for the one with the greatest id from table "myTable":
<?php
$con = mysqli_connect("hostname", "username", "password", "database"); // Connect
$totalRows = mysqli_query($con, "SELECT COUNT(*) FROM myTable"); // Get total row count
$mysqli_query($con, "DELETE FROM myTable WHERE id >= 0 LIMIT ($totalRows - 1);"); // Delete
?>
It's really useful because if you already only have 1 row left, you'll be left with LIMIT 0, which is what you want.

is there any alternative for this SELECT * FROM type WHERE tid='1' OR tid='2'; query?

is there any alternatives for this MySQL query?
SELECT * FROM type WHERE tid='1' OR tid='2';
here type is the table and tid is the id of the table and i want to select first 2 rows any way
totally there are 3 rows
the above query is working but at certain times server displays nothing ,everyone suggests it is because the server is getting confused due to the query given
any alternatives please....
the IDs are not guaranteed to be gapless. They most likely aren't.
What you need is the keyword LIMIT.
Just as Garr Godfrey already answered, you sort the table by the id (ascending by default) and then limit the results to 2 at maximum
SELECT tid, foo, bar FROM type ORDER BY tid LIMIT 2
You should have a look at the basic SQL keywords. They already do most of the stuff you usually need
maybe if those IDs don't exist you'd have problem, but there is nothing confusing about that query. Try
SELECT * FROM `type` ORDER BY ID LIMIT 2
that will select the lowest 2 ids

Trouble selecting a single random row from MySQL table

I am trying to select a user at random from a very simple table for the purposes of generating sample data.
The table has just two columns, the integer primary key users_id which has all the values from 1 to 46 inclusive, and uname which is a varchar(60).
The query
select relusers.uname from relusers where relusers.users_id=floor(rand()*46+1);
is returning multiple rows. Perhaps I've been staring at this for too long but I fail to see how the above query could ever return more than one row. floor() returns a single integer which is being compared to the primary key column. Including users_id in the selection shows multiple different IDs being selected. Zero rows as a result I can understand, but multiple? Any ideas?
Your code is returning multiple rows because rand() is evaluated on each row. So, you have the change of multiple matches. And a chance of no matches at all.
You can use your idea, but try it this way:
select relusers.uname
from relusers cross join
(selext #rand := rand()) const
where relusers.users_id = floor(#rand*46+1);
This generates just one random value and hence just one row. But, with only 46 rows, the order by method should perform well enough:
select relusers.uname
from relusers
order by rand()
limit 1;
select * from relusers order by rand() limit 1