Sort MySQL result by last value - php

I have a MySQL table set up with a field called clicks. It contains the clicks on certain banners separated by space (e.g. "9 80 47 306"). The field's type is text.
I want to get the entire table row and sort by whatever the last value in that field is (in this case it would be 306).
What I have so far doesn't work (obviously):
SELECT * FROM banners WHERE active = "1" ORDER BY clicked DESC
Is there a way I can achieve this using SQL only?
Thanks in advance!

Use substring_index() with -1:
SELECT *
FROM banners
WHERE active = "1"
ORDER BY substring_index(clicked, ' ', -1) DESC;
I should add that I agree that this is a bad way to store data. You should have a junction/association table. This would have one row per banner with a clicks column.
EDIT:
As the Joachim's comment wisely notes, we might want to change this to a number for sorting. In MySQL, I prefer + 0 because it does not report errors:
SELECT *
FROM banners
WHERE active = "1"
ORDER BY substring_index(clicked, ' ', -1) + 0 DESC;
Ugg, storing numbers as strings.

Try something like:
Order by substr(clicked,length(clicked-3),3)

Related

How to find the nearest string value from table?

I have a table name "test" having a column code (string format) and data is like:
U298765
U298799
U210430
U210499
B239856
Now I want to get data by input field entry. If a user write U298750, I want show the nearest value U298765 and for U210401,U210430.
You can use the right function to fetch the number and then use following logic.
Select t.*
From test t
Order by abs(Right(code, length(code)-1) - Right(your_input, length(your_input)-1))
Limit 1
I am consodering that you need the nearest based on numbers only.
Try below query:
select code from test
order by abs(abs(substring(code,2,length(code)))-abs(substring('U298750',2,length('U298750'))))
Limit 1
In place of 'U298750' use your input
You seem to just want:
select t.*
from t
where code >= ? -- the input value
order by code desc
limit 1;
The ordering of strings alphabetically is sufficient for getting the "next" value after the string. There is no need to convert anything to numbers.

Most efficient way of randomly selecting any mysql value given multiple values to match it to

Ok, so I have a list of values, and I want it so the user can select any 7 different options, and it'll randomly select x number of values from the table with any of those options.
The stucture is like ImgID (unique key) | SiteID | Other tables
Try 1:
The first method I tried was read the database for any selected values, and count the amount for each selected option. The amount of occurrences were stored in one variable (just call it num), and the total amount was calculated too. It then chose a random number between 1 and the max amount, ran through the num variable with the individual amounts, incrementing it until it went past the value, revealing which option value the random value landed on. This could randomly choose the option correctly, but it'd still require another random selection from the database, which leads into the next try.
Try 2:
The random value from the database seemed reasonable, but I thought why not just do it all at once and skip a lot of queries. I can't seem to get it working properly though, I was using this site - http://akinas.com/pages/en/blog/mysql_random_row/ and chose the bottom mehod to use. There's quite a few error messages from this - 'unable to save result set', 'execution was interrupted', 'lost connection to mysql server' and 'not a valid result resource'
The code is
for($i=0;$i<count($sites)-1;$i++){
$siteinfo = explode("#",$sites[$i]);
$siteid = $siteinfo[0];
$sitegroup = $siteinfo[1];
if($i!=0){
$sqlextra .= " OR ";
}
$sqlextra .= "SiteID='".$siteid."'";
}
$sql="SELECT * FROM ImageList WHERE ImgID >= (SELECT FLOOR( MAX(ImgID) * RAND()) FROM
ImageList) AND Valid='1' AND (".$sqlextra.") ORDER BY ImgID LIMIT 1";
if(mysql_query($sql, $mysql_connect)){}
else{echo mysql_error();}
And the sql output with a few of the option selected is
SELECT * FROM ImageList WHERE ImgID >= (SELECT FLOOR( MAX(ImgID) * RAND()) FROM ImageList) AND Valid='1' AND (SiteID='6' OR SiteID='7') ORDER BY ImgID LIMIT 1
I'm not very good at mysql so not sure if I've gone wrong somewhere, but if anyone has a better way of doing this or just knows why mine isn't working, it'd be appreciated, cheers
select * from ImageList where Valid='1' AND (SiteID='6' OR SiteID='7') order by RAND() Limit 1
This should be a lot more efficient :)

Mysql query one random?

I have issuse with displaying random item from table, is there way to display just one random item, but not the item i preffered to not to be displayed?
I have table PRODUCT
and rows
ID
TITLE
URL_TITLE
and
$link = "coffee";
I want to display random just one product from table PRODUCT, but not the the same i have in $link
What i want to say i just want random item from table, but not when in $link="coffee" to get that random element
p.s
$link in in URL_TITLE row :)
This should help:
SELECT ID, TITLE, URL_TITLE
FROM PRODUCT
WHERE URL_TITLE != "coffee"
ORDER BY RAND()
LIMIT 1;
Note that in some versions of SQL, != is written <>.
Obviously, you want to select all rows or a different subset, just use SELECT * or whatever you need.
Edit: as per HamZa's comment and James' answer, using ORDER BY RAND() is bad practice on large tables. You could potentially generate a random ID and select that, checking that it's not your illegal one, but if you have a whole bunch that you can't select, you could potentially call this query a ton of times (which is bad).
Using rand() in queries is not ideal, especially in large tables, but even small ones as you never know when they'll grow (ie site or service exceeds your expectations etc).
You can use it like this:
select item from product where item != '$link' ORDER BY rand() LIMIT 1
But you should use something better, like temp tables, or you could select all the IDs from the database in one query, use PHP to select a random one from them all, then use the ID selected by PHP and grab the data from the database.
SELECT id
FROM PRODUCT
WHERE URL_TITLE != "coffee"
ORDER BY RAND()
LIMIT 1;
Although I don't know PHP, I think a simple way to do it is to pass the $link value as part of a where condition.
Using 'pure' SQL:
select *
from product
where URL_TITLE <> 'coffee'
order by rand()
limit 1

php and mySQL how to get highest value in a varchar column

In a case where I have a column that needs to be unique eg. product:eggs, tomatoes, pepper, pepper1, pepper2
and before i insert another pepper i need to check the last integer, and add 1 to it, so the next pepper would be 'pepper3'
How would i do this?
Thanks in advance
The easy way is to have two columns: the first for the label and the second for the id.
It's never good to mix up various information in the same column.
Then you could do something like :
SELECT MAX(product_id) FROM ... WHERE label = "pepper"
and
SELECT CONCAT(label,product_id) FROM ... WHERE id = ...
Returns what you want.
I would try something like this:
SELECT LEFT(product_name, 6) AS product_name_plain,
CAST(RIGHT(product_name, 6) AS UNSIGNED) AS product_number
FROM product_table
WHERE product_name_plain = "pepper"
ORDER BY product_number DESC
LIMIT 1
The SELECT breaks apart product names into the plain name ("pepper"), and an unsigned integer version of the product number (3).
The WHERE clause identifies the peppers.
The ORDER BY will sort them (which should result in the last pepper being the first result)
The LIMIT will only fetch the one result.
Note that "6" and "pepper" are hard-coded in this query, your code would have to put them in. 6 is the length of "pepper."

php / mysql - how to get rankings of users?

for example i have a table like this :
name rating
matei 124
andrei 20
serj 25
john 190
mike 96
andy 245
tom 73
i need to output something like this(order by rating):
john's position is 2; or, tom's position is 5; (i don't need to get all result , just one )
How can I achieve this?
Thanks in advance
Generally order of rows in a query result is not guaranteed by MySQL unless ordering is explicitly specified with ORDER BY clause. If you have some separate ordering column, you may use query like the following:
SELECT count(1) as position
FROM table
WHERE order_column <= {john's order_column value};
If you don't have ordering column, I'd recommend you to define first, what does "john's position" and "tom's position" mean.
UPDATE:
AFAIU, you want to get position in list sorted by rating (sorry, I initially did not get it). So, rating would be your order_column. In this case, you should decide, how do you calculate position, if two guys have equal rating (who's position is higher?).
So, the query may look in the following way:
SELECT count(1) as position
FROM table
WHERE
rating > (SELECT rating FROM table WHERE id={user's ID});
SELECT COUNT(*) + 1
FROM users
WHERE (rating, name) <
(
SELECT rating, name
FROM users
WHERE name = 'john'
)
Note that if you will have duplicates on both name and rating, this query will assign the same rating to both of them.
Tables are more formally known as relations in database literature - they are not guaranteed to be ordered (they are sets of "tuples"), so your question doesn't make sense. If you need to rely on an order/position, you need to define an additional column (like an auto-incrementing ID column) to capture and store that info.
Is this any help > http://craftycodeblog.com/2010/09/13/rownum-simulation-with-mysql/ ?
Would offset not work like so?
SELECT * FROM Table ORDER BY rating DESC LIMIT 1,6
This would return 1 row that has been off setted by 6 rows ? or am I mistaken, the syntax would be
SELECT * FROM Table ORDER BY rating DESC LIMIT 1 , {{POS}}

Categories