MySQL MAX subquery - php

I have a problem with MySQL at this moment.
I'm trying to determine the highest float value from my table like this:
SELECT `id`
FROM `LOTRESULTS`
WHERE
`value`= (SELECT MAX(value) FROM `LOTRESULTS`) AND
`lot_id` = 180
ORDER BY `id` DESC
LIMIT 1
This works whenever I choose let's say id 180, but none of the other combinations work.
There are 3 entries with 180 as lot_id, and 2 occurences with 179 as lot_id, etc.
It just works randomly, it fails on most of the entries in the DB.
Am I doing something wrong? Should I change the datatype of the value column?
Thanks in advance guys!
p.s. I've also tried:
SELECT `id` FROM `LOTRESULTS` WHERE `value`= (SELECT MAX(value) FROM
`LOTRESULTS`) AND `lot_id` = 180
and
SELECT `id` FROM `LOTRESULTS` WHERE `value`= (SELECT MAX(value) AS
`value` FROM `LOTRESULTS`) AND `lot_id` = 180
with the same results...

Your inner query is going to fetch the highest value field ANYWHERE in the table, regardless of which lot it's part of. The outer query then tries to retrieve all the ids that have that max value AND are part of a specific lot.
If the max value belongs to lot 123, but you're fetching the ids for lot 456, you'll get no results.
The query should be:
SELECT id
FROM LOTRESULTS
WHERE value = (
SELECT MAX(value) AS value
FROM LOTRESULTS
WHERE lot_id = 180
) AND lot_id = 180
The doubled lot_id = 180 handles the case where two+ different lots may share the same maximum value. Without the 'outer and', you'd get the ids for the two+ lots.

You don't really have to use sub-query, or JOIN,
a simple where + order + limit will do :-
SELECT id FROM LOTRESULTS WHERE lot_id = 180 ORDER BY value DESC LIMIT 1;

SELECT *
FROM LOTRESULTS
WHERE whatever...
ORDER BY value DESC
LIMIT 1

Related

Select second, third, fourth, fifth, largest number

I have a question about how to select the second, third, fourth, and fifth largest number in a table. To select the biggest row I use:
$max = SELECT max(money) FROM table
Right now I want to specify $second_max, $third_max, $fourth_max and $fifth_max.
Does someone know how to change my previous SQL select max() easy to specify second max, third max etc...?
I do not want to use:
select money from table order by money desc limit 5;
Because I want them all in different variables.
select money from table order by money desc LIMIT 5
Probably the easiest way is to get them on separate rows:
select t.money
from table t
group by t.money
order by money desc
limit 5;
The next easiest thing is to put them in a comma-separated list:
select group_concat(money order by money desc) as monies
from (select t.money
from table t
group by t.money
order by money desc
limit 5
) T
Just this:
SELECT money
FROM yourtable
ORDER BY money DESC
LIMIT 5
You'll get a 5-record result set, ordered by the top money values - assuming you actually have 5+ records in the table.
USE SQL
select money from table order by money desc limit 5;
The five rows are there as max, secondary,... value of money.
In ORACLE you could do the following :
SELECT *
FROM (
SELECT ADRESSID,
ROW_NUMBER() OVER (ORDER BY ADRESSID DESC) AS ROW_NUM
FROM ADRESSTABLE
) t
WHERE ROW_NUM = 1
OR ROW_NUM = 3
OR ROW_NUM = 5;

How do I sort the following table & get those top5- 5 recoreds,top20- twenty records?

This query giving strange result:
SELECT `user_id`,`rankType`
FROM `ranks`
WHERE `user_id` =23
AND (`rankType` = "top5"
OR `rankType` = "top20")
ORDER BY rankType
LIMIT 0 , 30
here the SQLfiddle.
Want I am trying to achieve is:
1)To get only 5 records of top5 rank type, 20 records of rank type top20
2)I want to show the result in ascending order of rank type.(but if you see in the demo fiddle it's showing apposite, may be it is only considering 2 from 20 & 5)
(SELECT `id`,`user_id`,`rankType`
FROM `ranks`
WHERE `user_id` =23
AND `rankType` = "top5"
ORDER BY rankType
LIMIT 0, 5)
union
(SELECT `id`,`user_id`,`rankType`
FROM `ranks`
WHERE `user_id` =23
AND `rankType` = "top20"
ORDER BY rankType
LIMIT 0, 20)
If later on you want to add another set of sorting/filtering columns, wrap it all into something like
select * from ( /* previous query goes here */ ) tt
where id > 100
order by id
Note that ranktype is varchar, so it's sorted lexicographically, so top20 < top5. You'll have to employ natural sorting or some other means to get it right.
SELECT `id`,`user_id`,`rankType`
FROM `ranks`
WHERE `user_id` =23
AND `rankType` = "top5" limit 5
union
SELECT `id`,`user_id`,`rankType`
FROM `ranks`
WHERE `user_id` =23
AND `rankType` = "top20" limit 20
Your result is actually in ascending order, since column rank_type is of varchar type top20 comes first than top5 as in string comparison.
If you only want to deal between top5 and top20, a dirty solution could be:
ORDER BY rankType desc
One possibility without doing two queries and UNIONing them:
ORDER BY FIND_IN_SET(rankType,'top5,top20')

select the 3 highest values using php mysql query

I have a table like this:
`id|value
1|2
2|8
3|5
4|6
5|10
6|7`
I need a query to pull AND sum the 3 highest values. So the correct query would pull the following:
3 highest:
5|10
2|8
6|7
Sum of 3 highest values = 25
I feel like this should be pretty simple but i'm having a tough time! Thanks for your help
SELECT SUM(Value) AS SumOfTop3Values
FROM (
SELECT Value
FROM Table
ORDER BY Value DESC
LIMIT 3
) AS sub
I think you need to wrap this in a subquery:
SELECT SUM(value) AS total FROM (
SELECT value FROM table
ORDER BY value DESC
LIMIT 3
);
To have MySQL return highest 3 values and their Sum in a 4th row, you can use (aasuming that id is the Primary Key of the table):
SELECT id, SUM(value)
FROM
( SELECT id, value
FROM TableX
ORDER BY value DESC
LIMIT 3
) AS tmp
GROUP BY id
WITH ROLLUP ;

SQL position of row(ranking system) WITHOUT same rank for two records

so I'm trying to create a ranking system for my website, however as a lot of the records have same number of points, they all have same rank, is there a way to avoid this?
currently have
$conn = $db->query("SELECT COUNT( * ) +1 AS 'position' FROM tv WHERE points > ( SELECT points FROM tv WHERE id ={$data['id']} )");
$d = $db->fetch_array($conn);
echo $d['position'];
And DB structure
`id` int(11) NOT NULL,
`name` varchar(150) NOT NULL,
`points` int(11) NOT NULL,
Edited below,
What I'm doing right now is getting records by lets say
SELECT * FROM tv WHERE type = 1
Now I run a while loop, and I need to make myself a function that will get the rank, but it would make sure that the ranks aren't duplicate
How would I go about making a ranking system that doesn't have same ranking for two records? lets say if the points count is the same, it would order them by ID and get their position? or something like that? Thank you!
If you are using MS SQL Server 2008R2, you can use the RANK function.
http://msdn.microsoft.com/en-us/library/ms176102.aspx
If you are using MySQL, you can look at one of the below options:
http://thinkdiff.net/mysql/how-to-get-rank-using-mysql-query/
http://www.fromdual.ch/ranking-mysql-results
select #rnk:=#rnk+1 as rnk,id,name,points
from table,(select #rnk:=0) as r order by points desc,id
You want to use ORDER BY. Applying on multiple columns is as simple as comma delimiting them: ORDER BY points, id DESC will sort by points and if the points are the same, it will sort by id.
Here's your SELECT query:
SELECT * FROM tv WHERE points > ( SELECT points FROM tv WHERE id ={$data['id']} ) ORDER BY points, id DESC
Documentation to support this: http://dev.mysql.com/doc/refman/5.0/en/sorting-rows.html
Many Database vendors have added special functions to their products to do this, but you can also do it with straight SQL:
Select *, 1 +
(Select Count(*) From myTable
Where ColName < t.ColName) Rank
From MyTable t
or to avoid giving records with the same value of colName the same rank, (This requires a key)
Select *, 1 +
(Select Count(Distinct KeyCol)
From myTable
Where ColName < t.ColName or
(ColName = t.ColName And KeyCol < t.KeyCol)) Rank
From MyTable t

mysql row counter

I have a mysql table. It has auto increment on the id. but I regularly delete rows so the numbers are all over the place. I need to get the last n rows out, but because of deletions, the common way of using the max of the autoincremented id column doesn't work well...
1 - Is their another way to get the bottom 50?
2 - Is their a way to get rows by actual row number? so if I have 4 rows labelled 1,2,3,4 delete row 2 then it will become 1,2,3 rather than 1,3,4?
SELECT ... ORDER BY id DESC LIMIT 50
SELECT *
FROM TABLE
ORDER BY id DESC
LIMIT 50
EDIT
To pick the last 50, but sort by id ASC
SELECT X.*
FROM ( SELECT *
FROM TABLE
ORDER BY id DESC
LIMIT 50
) X
ORDER BY X.id
1 - First get total row count like
SELECT COUNT(*) AS c FROM ...
then use
SELECT ..... LIMIT [start],[count]
2 - One idea is to use view , or procedure, but this is much more harder and may be used when there is no other way to avoid this
1 - Is their another way to get the bottom 50?
SELECT * FROM table_name ORDER BY record_id DESC LIMIT 50
2 - Is their a way to get rows by actual row number? so if I have 4 rows labelled 1,2,3,4 delete row 2 then it will become 1,2,3 rather than 1,3,4?
SELECT * FROM table_name
1 - Yes but it is ugly afaik, you do a
SELECT whateveryouwant FROM table ORDER BY yourprimarykey DESC LIMIT 50
the you fetch the rows into an array and reverse the array, in php :
$r = mysql_query('SELECT * FROM table ORDER BY primarykey DESC LIMIT 50');
$set = array();
while($row = mysql_fetch_assoc($r)) $set = $row;
$set = array_reverse($set);
foreach($set as $row) {
// display row ...
}
2 - You'll have to manage your primary key by yourself, its a bit risky ...

Categories