Mysql: return orderBy ranking - mysql

Is there a way to return the Mysql orderBy ranking as part of the resulting record?
For example, lets say I have a comment table where I am querying results ranked by:
comment_rating and comment_length, using orderBy('r.comment_rating*r.comment_length').
Now I want the resulting records to include the value of their respective comment_rating*comment_length calculations.
Is this possible?
edit: also, does doctrine perform the ranking calculations twice if I do this and also use the same algorithm for orderBy?

Do you mean something like:
SELECT *, (comment_rating * comment_length) AS ranking FROM comment ORDER BY ranking DESC
Edit
Haven't used Doctrine, but after a quick glance at the documentation, I guess it would be something like this:
$q = Doctrine_Query::create()
->select('*, (comment_rating * comment_length) AS ranking')
->from('comment')
->orderBy('ranking');
$comments = $q->execute();

Try this :
Select comment_rating, comment_length,
(comment_rating * comment_length) as rat_len
From comment
OrderBy rat_len

All you need to do is include
(comment_rating*comment_length) as comment_ranking
in the SELECT field list.

SELECT
comment_rating,
comment_length,
comment_rating*comment_length AS comment_rank
FROM
tablename
ORDER BY
comment_rank;

Try this:
SELECT <yourFields>, (r.comment_rating * r.comment_length) AS Rating FROM ...
Documentation:
Doctrine Query Language: Aggregate-values.

Related

Mysql subquery or something better

I am somewhat new to mysql and I am having an issue on how I should best write the following query. Say I have a table that has a datetime column as well as a few others I want to search on. Since this is just one table, I don't think a join statement would be appropriate here (but I may be wrong since I have not done much in the way of join statements) and I think a subquery is what I need here. So my initial query is to search the table based on a search string the user entered and then I want to limit that on a datetime (start date and end date) also specified by the user in an HTML form.
Table Schema
id, datetime, host, level, message
I want to select any rows that contain $searchstring first so something like ...
SELECT * FROM $table WHERE (level LIKE '%$searchstring%') OR (message LIKE '%$searchstring%') LIMIT $offset,$limit
If I want to limit the above results also by the datetime column, the query would look something like this ...
SELECT * FROM $table WHERE (datetime >='$startdate') AND (datetime < '$enddate')
How can I best merge these queries into one so I can first get any rows that match the search query and then further limit the rows by the start and end datetime?
TIA
You can achieve that by using a single where condition.
In your case:
SELECT * FROM $table WHERE ((level LIKE '%$searchstring%') OR (message LIKE '%$searchstring%')) AND (datetime >='$startdate') AND (datetime < '$enddate') LIMIT $offset,$limit
You don't have to use a JOIN but only add a condition
SELECT *
FROM $table
WHERE (level LIKE '%$searchstring%' OR message LIKE '%$searchstring%')
AND
datetime >='$startdate'
AND datetime < '$enddate'
LIMIT $offset,$limit

MySQL order when using IN ()

I am getting some records from sorted table and would like to ask some other table for records with the same ... lets say ... id.
SELECT * FROM duckies WHERE fluffy_id IN (<array_of_fluffy_ids>) ...
Is there any way to order the query result exactly the same way as fluffy_ids in IN() clause?
Yes, there is. Use FIELD() function:
SELECT
*
FROM
duckies
WHERE
fluffy_id IN (<array_of_fluffy_ids>)
ORDER BY
FIELD(fluffy_id, <array_of_fluffy_ids>)

Mysql query based on a list of specific random numbers?

I'm trying to do a query based on specific numbers which at this stage I only need to hardcode into the page as comma separated values.
2312,2431,2439,2440,2442,....
But I can not use between because the numbers in between may not be relevant
So how do I do a query of this type?
$sql= "SELECT * FROM table
WHERE pc=2431 OR pc=2439 OR
pc=2440 OR pc=2442 OR
pc=2443 OR pc=2444 OR
pc=2445 OR pc=2446 OR
pc=2312 AND v=1
ORDER BY id DESC
LIMIT $offset, $rowsperpage";
I tried this and kind of works but there must be a better way.
Thanks in advance
Indeed there is... You can use the IN operator so that the query becomes:
SELECT *
FROM table
WHERE pc IN (2431,2439,2440,2442,2443,2444,2445,2446,2312)
AND v=1
ORDER BY id DESC
LIMIT $offset, $rowsperpage
Simples :o)
For more info check out the MySQL documentation at http://dev.mysql.com/doc/refman/5.5/en/comparison-operators.html#function_in
I would suggest a little improvement to other answers:
$pcs = array(2431,2439,2440,2442,2443,2444,2445,2446,2312);
"SELECT *
FROM table
WHERE pc IN (" . implode(",", $pcs) . ")
AND v=1
ORDER BY id DESC
LIMIT $offset"
this way if later your ids will change and you have several queries using them you will have to update only one place instead of N (where N is number of queries). If you use these ids in many different files, consider making a constant

MySQL select with subquery having replace

So I have a data with format like ;1;;2; and then I need to use this number in a query so I thought I'd convert it to 1,2 and use that in a IN condition. In my table, the result should return 2 rows but instead it is returning only 1 row.
My query is like this. The subquery return 1,2 with no problem but only 1 row is retrieve.
select *
from wt_lists
where id IN ((select replace (replace(sendto, ';;',','),';','')
from wt_stats where statsid IN (1)))
But when I try it with this. It returns the correct result, which in my case is 2 rows.
select *
from wt_lists
where id IN (1,2)
What am I missing here?
Comma delimited strings need to be explicitly defined in the query in order to be used in the IN clause - there's countless examples on SO where people need to use dynamic SQL to incorporate user submitted comma delimited strings.
That said, I have a solution using the FIND_IN_SET function:
SELECT DISTINCT wl.*
FROM WT_LISTS wl
JOIN (SELECT REPLACE(REPLACE(ws.sendto, ';;',','),';','') AS ids
FROM WT_STATS ws
WHERE ws.statsid = 1) x ON FIND_IN_SET(wl.id, x.ids) > 0
You are replacing the string:
';1;;2;'
To:
'1,2'
So, you SQL query looks like:
select * from wt_lists where id IN ('1,2') from wt_stats where statsid IN (1)
To use IN clause you need select different values in different rows.
I found this store procedure that does exactly what you need.
http://kedar.nitty-witty.com/blog/mysql-stored-procedure-split-delimited-string-into-rows/
I have not tested, but it is the way.
Obs: Like David said in the comments above, parsing the data in your application is a better way to do this.

mysql query, reuse columnnames in query

I have a mysql query, something like this:
SELECT users*100 as totalusers, totalusers*90 AS totalsalerys FROM table
As you can see I want to reuse the totalusers when calculating totalsalerys so I son't have to write the same code again. That dosen't seem to work in mysql, is there another easy way to do this?
My query is just an example, change the *100 and *90 to some very long formula and you might see what i mean..
SELECT (#r := users * 100) as totalusers,
#r * 90 AS totalsalerys
FROM table
You can also use a subquery as #Tom Ritter advices, but it's not friendly to ORDER BY ... LIMIT ... clause.
In MySQL, all results of the inner subquery will be fetched before applying any filters in the outer subquery.
I believe you would have to copy/paste the formula or use a subquery. The below would work in T-SQL, but I imagine it'd work in MySQL as well since it's pretty simple.
SELECT
x.totalusers, x.totalusers*90 AS totalsalerys
FROM (
SELECT users*100 as totalusers FROM table
) x