I have two MySQL queries which are very similiar however they return a COUNT() upon a specific WHERE clause (type), so I was wondering if they could be merged into 1 query seeing as only the WHERE clause (type) differenciates the two?
Query 1:
SELECT COUNT(referral_id) AS in_count
FROM referrals
WHERE author = '{$author}'
AND type = 'in'
AND ip_address = '{$ip_address}'
LIMIT 1
Query 2:
SELECT COUNT(referral_id) AS out_count
FROM referrals
WHERE author = '{$author}'
AND type = 'out'
AND ip_address = '{$ip_address}'
LIMIT 1
All help is greatly appreciated :B
SELECT SUM(IF(type='in',1,0)) as in_count,
SUM(IF(type='out',1,0)) as out_count
FROM referrals
WHERE author = '{$author}' AND
ip_address = '{$ip_address}'
LIMIT 1
You just need a GROUP BY clause.
SELECT COUNT(referral_id) AS count, type
FROM referrals
WHERE author = '{$author}'
AND ip_address = '{$ip_address}'
GROUP BY type
LIMIT 1
Related
I just want to perform multiple table operations in single query. The query is:
select name,sno , id as ids ,(select sum(amount) from client_credits
where user_id = ids) As total from clients where sno = '4' and total > '0'
This query is not working when I am trying use ** total > 0 **. Is there any other possibility ways? Please help me.
total is an alias. Aliases are not resolved when the WHERE clause is reached.
Try: where sno = 4 having total > 0
Alternatively, and more efficiently:
SELECT `c`.`name`, `c`.`sno`, `c`.`id`, SUM(`ccr`.`amount`) AS `total`
FROM `clients` AS `c`
JOIN `client_credits` AS `ccr` ON `c`.`id`=`ccr`.`user_id`
WHERE `c`.`sno` = 4
GROUP BY `c`.`id`
Notice how the total > 0 part is gone? That's because if there are no rows to join, then nothing will be joined and the rows are removed from the result ;)
While I was using subqueries, I came across this situation. Could any one explain me which one is efficient and also, the situations where case 1 is better than case 2 or vice versa.
In case 1, I have used 3 subqueries and in total of 4 select operations, it need to perform.
CASE 1
SELECT * FROM t
WHERE Cid = (SELECT cid FROM s WHERE id = $sid)
AND Bid = (SELECT bid FROM s WHERE id = $sid)
AND Eid = (SELECT eid FROM s WHERE id = $sid)
In case 2, I have retrieved some values from database and perform mysql query again. Here mysqli_query is performed twice but in the case 1 only once we have used.
CASE 2
$res = mysqli_query($con,"SELECT cid,bid,eid FROM s WHERE id = $sid");
$row = mysqli_fetch_array($r,MYSQL_ASSOC);
"SELECT * FROM t WHERE Cid = $row[cid] AND Bid = $row[bid] AND Eid = $row[eid]";
or any other better solution? Any help is greatly appreciated. Thanks
Neither. You don't need subqueries when you can use a JOIN.
SELECT t.* FROM t
JOIN s ON t.Cid = s.cid AND t.Bid = s.bid AND t.Eid = s.eid
WHERE s.id = $sid
i have this poll thing, Poll A, has 3 options let's say: Option a option b option c, option a got 3 votes, option b got 2 votes option c got 3 votes,
OPTIONS VOTES
option a 3
option b 2
option c 3
and i have this mysql query which gets the options and orders by votesCount, limit 1 to get the top answer, but in my example, there are two options on top, they both have the highest values, i want a query to get those two options, n not only one, so i have to get rid of LIMIT 1
Mysql query is
$query = "SELECT `option` FROM `options` WHERE `pid` = '$pid' AND `votesCount` != '0' ORDER BY `votesCount` DESC LIMIT 1";
any suggestion?
Here is a standard way in any SQL dialect:
select p.*
from poll p
where p.votes = (select max(votes) from poll)
Thanks to #Gordon Linoff for the hint, this is how it is now
$query = "SELECT `option` FROM `options` WHERE `pid` = '$pid' AND `votesCount` = (SELECT MAX(`votesCount`) FROM `options` WHERE `pid` = '$pid' ORDER BY `votesCount` DESC LIMIT 1)";
///Just a DB function, don't mind the 0, i'm using a class
$res = $db->get_rows($db->select($query),0);
$merged = array();
foreach ($res as $r){
$merged[] = $r->option;
}
$merged = implode(',',$merged);
return $merged;
Here's the situation:
In my database i have a table with threads, and a table with replies. Both have a Timestamp field.
Now i am developing a forum and wish to order threads in the following manner:
If the thread has replies, then: ORDER BY tblReply.Timestamp DESC
Else, the thread has no replies: ORDER BY tblThread.Timestamp DESC
I do not know how to combine these 2 in one statement.
My query as it is now:
SELECT `PK_ThreadID`, `Title`, `tblUsers`.`Username`, `tblThread`.`Date`, count(tblReply.FK_ThreadID) AS number_replies FROM (`tblThread`)
JOIN `tblUsers` ON `tblUsers`.`PK_UserID` = `tblThread`.`FK_UserID`
LEFT JOIN `tblReply` ON `tblReply`.`FK_ThreadID` = `tblThread`.`PK_ThreadID`
WHERE `isExpertQuestion` = 0 AND `isPublic` = 1
GROUP BY `PK_ThreadID`
ORDER BY max(tblReply.Date)` desc
//Here it only orders by reply date, so threads with no replies appear at the bottom
How do i achieve the ordering i want in this query?
Like this probably:
SELECT `PK_ThreadID`, `Title`,
`tblUsers`.`Username`,
`tblThread`.`Date`,
count(tblReply.FK_ThreadID) AS number_replies
FROM (`tblThread`)
JOIN `tblUsers` ON `tblUsers`.`PK_UserID` = `tblThread`.`FK_UserID`
LEFT JOIN `tblReply` ON `tblReply`.`FK_ThreadID` = `tblThread`.`PK_ThreadID`
WHERE `isExpertQuestion` = 0 AND `isPublic` = 1
GROUP BY `PK_ThreadID`
ORDER BY
CASE WHEN COUNT(tblReply.FK_ThreadID) > 0 THEN tblReply.Timestamp
WHEN COUNT(tblReply.FK_ThreadID) = 0 OR tblReply.FK_ThreadID IS NULL
THEN tblThread.Timestamp
END DESC
I am what you would call a 'noob' at MySQL. I can insert/edit/select stuff, but anything more advanced than that stumps me. I have two tables in my database:
Table 'reviews'
id int(11)
review varchar(2500)
game int(11)
user int(11)
title varchar(200)`
and Table 'review_rating'
user int(11)
review int(11) // Corresponds to `reviews.id`
like tinyint(1)
Here is my question: Is it possible to use ORDER BY on the reviews table to order the result by the total number of review_ratings with 'like' = 1 (where 'review' = the id of the 'reviews' table) divided by the total number of review_ratings (where 'review' = the id of the 'reviews' table).
Example:
SELECT *
FROM `reviews`
WHERE `game` = ?
ORDER BY (total number of review_ratings where review = reviews.id and like = 1 /
total number of review_ratings where review = reviews.id)
LIMIT 0, 10
SELECT t.review,
Score = CASE WHEN TotalReviews<> 0 THEN LikedReviews/TotalReviews ELSE NULL END
FROM (
SELECT *,
(SELECT COUNT(*) FROM review_rating WHERE review = r.review) AS TotalReviews ,
(SELECT COUNT(*) FROM review_rating WHERE review = r.review AND like = 1) AS LikedReviews,
FROM review r
WHERE game = ?
)t
ORDER BY t.review, Score
I think it's clearer to put it in the SELECT clause:
SELECT reviews.*,
( SELECT SUM(like) / COUNT(1)
FROM review_ratings
WHERE review = reviews.id
) like_ratio
FROM reviews
WHERE game = ?
ORDER
BY like_ratio DESC
LIMIT 10
;
Notes:
Not tested; I'm away from a MySQL box at the moment.
I think you could move the subquery to the ORDER BY clause if you wanted, but it seems like a useful thing to retrieve, anyway.
I'm not sure how the above will behave if a given review has no ratings. You may need to use a CASE expression to handle that situation.
something like this would order by the total review_rating per review:
select( count(review.id) as 'total' from reviews join review_rating on review.id = review_rating.review group by review.id) order by total
the math is not exactly what you had but hopefully you will get it