How to add multiple limits in mysql query? - php

I want to select SUM of last 200,100 and 50 rows of close price from a table in a single query.
given below is the query for 200 rows.
SELECT SUM(Close_price) as tot200 FROM cash_data ORDER BY date_added LIMIT 0,200
can anyone help me with this.

You can use sub queries -
SELECT
(SELECT SUM(Close_price) FROM cash_data ORDER BY date_added LIMIT 0,200) as tot200,
(SELECT SUM(Close_price) FROM cash_data ORDER BY date_added LIMIT 0,100) as tot100,
(SELECT SUM(Close_price) FROM cash_data ORDER BY date_added LIMIT 0,50) as tot50

To make it in a single select without any subselects you can use a ranking varaible and sum conditionally
SELECT #rank := #rank + 1,
SUM(case when #rank <= 50 then Close_price else 0 end) as top_50_sum,
SUM(case when #rank <= 100 then Close_price else 0 end) as top_100_sum,
SUM(case when #rank <= 200 then Close_price else 0 end) as top_200_sum
FROM cash_data
cross join (select #rank := 0) r
ORDER BY date_added
LIMIT 0,200

Thanks for all the replies. Actually both the answers are working but i choose the second one and made some changes for my need. Below is the final query
SELECT
(SELECT SUM(Close_price)/200 FROM (SELECT Close_price FROM cash_data WHERE SERIES='$series' AND SYMBOL='$symbol' AND date_added <= '$date' ORDER BY date_added DESC LIMIT 0,200) as tot200) as avg200,
(SELECT SUM(Close_price)/100 FROM (SELECT Close_price FROM cash_data WHERE SERIES='$series' AND SYMBOL='$symbol' AND date_added <= '$date' ORDER BY date_added DESC LIMIT 0,100) as tot100) as avg100,
(SELECT SUM(Close_price)/50 FROM (SELECT Close_price FROM cash_data WHERE SERIES='$series' AND SYMBOL='$symbol' AND date_added <= '$date' ORDER BY date_added DESC LIMIT 0,50) as tot50) as avg50
Thank you all.

Related

MySQL - Combine two queries, or limit results

I have a table that tracks recently updated pages, each page has a type. I want to limit the results so that we only pull 3 pages of type x, and 3 of type y, but still have them sorted by lastUpdated. I can't figure out how to do this in mysql
SELECT * from recentlyUpdated WHERE type = 'x' DESC LIMIT 3
SELECT * from recentlyUpdated WHERE type = 'y' DESC LIMIT 3
then ...
ORDER BY lastUpdated DESC
This may help you;)
(SELECT * from recentlyUpdated WHERE type = 'x'lastUpdated ORDER BY DESC LIMIT 3)
UNION ALL
(SELECT * from recentlyUpdated WHERE type = 'y'lastUpdated ORDER BY DESC LIMIT 3)
ORDER BY lastUpdated DESC
One obvious way to do it is using UNION:
SELECT *
FROM (
SELECT *
FROM recentlyUpdated
WHERE type = 'x'
LIMIT 3
UNION ALL
SELECT *
FROM recentlyUpdated
WHERE type = 'y'
LIMIT 3) AS t
ORDER BY lastUpdated DESC
Alternatively, you can use variables:
SELECT *
FROM (
SELECT *,
#seq := IF(#t = type, #seq + 1,
IF(#t := type, 1, 1)) AS seq
FROM recentlyUpdated
CROSS JOIN (SELECT #seq := 0, #t := '') AS vars
WHERE type IN ('x', 'y')
ORDER BY type) AS t
WHERE t.seq <= 3
ORDER BY lastUpdated DESC

Select top score only from MySQL database

I have a MySQL statement that pulls back the top 15 scores from a table of users.
select #rownum:=#rownum+1 'rank', driverName, teamColour, totalScore, totalTime, didTyreChange from entries p, (SELECT #rownum:=0) r WHERE totalTime > 1000 and progress = 19 order by totalScore desc, totalTime asc limit 15
The conditions are, that the player must have completed all the questions (where progress = 19) and the final time must be more than 1 second (totalTime > 1000). The statement also returns their rank as a variable (#rownum:=#rownum+1 'rank').
The result of this query is the following
What I now want to do, is extend the results to only show a players top score. I have had a look at DISTINCT and GROUP BY but get these results with the following GROUP BY statement
select #rownum:=#rownum+1 'rank', driverName, teamColour, totalScore, totalTime, didTyreChange from entries p, (SELECT #rownum:=0) r WHERE totalTime > 1000 and progress = 19 group by driverName order by totalScore desc, totalTime asc limit 15
and nowhere with DISTINCT as I get error code 1064. I have tried both
select #rownum:=#rownum+1 'rank', DISTINCT(driverName), teamColour, totalScore, totalTime, didTyreChange from entries p, (SELECT #rownum:=0) r WHERE totalTime > 1000 and progress = 19 order by totalScore desc, totalTime asc limit 15
and
select DISTINCT driverName, #rownum:=#rownum+1 'rank', teamColour, totalScore, totalTime, didTyreChange from entries p, (SELECT #rownum:=0) r WHERE totalTime > 1000 and progress = 19 order by totalScore desc, totalTime asc limit 15
Neither provides the desired results. I'm wondering if there is an easy way to achieve this within the statement, or to do it on the PHP side of things instead.
The desired resultL
viper 1 9810
Maverick 2 25420
Racer roasty 3 28850
.. .
... 15
In other words, no user should appear in the results twice, only the quickest totalTime is displayed for each user.
Slimmed down SQLFiddle here http://sqlfiddle.com/#!2/36d3dc/7 (8000 char limit reached).
SELECT #i:=#i+1 rank, a.*
FROM
( SELECT x.*
FROM entries x
JOIN (SELECT drivername, MIN(totaltime) min_totaltime FROM entries WHERE progress = 19 AND totaltime > 1000 GROUP BY drivername) y
ON y.drivername = x.drivername
AND y.min_totaltime = x.totaltime
) a
, (SELECT #i:=0) i
ORDER
BY totalScore desc, totalTime asc;
http://sqlfiddle.com/#!2/36d3dc/17
If I understood your problem correctly then below query will help you:
select *,#rownum:=#rownum+1 as 'rank' from (select * from (select driverName, teamColour, totalScore, totalTime, didTyreChange from entries p WHERE totalTime > 1000 and progress = 19 order by totalScore desc, totalTime asc )a group by driverName)c , (select #rownum:=0)f
This should do:
select #rownum:=#rownum+1 'rank', driverName, totalScore, MIN(totalTime)
from entries p, (SELECT #rownum:=0) r
WHERE totalTime > 1000 and progress = 19
group by driverName
order by totalScore desc, totalTime asc
http://sqlfiddle.com/#!2/36d3dc/20/0

How to retrieve sum of 5 top score from a table in mysql

I am working on a project where i need to extract the sum of top 5 score for every team sorted in descending order from a table.
Here is the table structure
Can anyone help me for this query
Thanks
SELECT team_id AS `team` , (
SELECT SUM( score )
FROM `table`
WHERE team_id = `team`
ORDER BY score DESC
LIMIT 5
) AS `score`
FROM `table`
GROUP BY team_id
ORDER BY `score` DESC
SELECT sum(score) as total
FROM
(SELECT score FROM your_table ORDER BY by score DESC LIMIT 1,5)
$count = 0;
foreach($this->conn->query("SELECT * FROM scores DESC LIMIT 5") as $rows){
$count += $rows;
}
Replace foo with your name.
SELECT team_id, SUM(score) AS `score`
FROM `foo`
WHERE
(SELECT COUNT(*)
FROM `foo` AS t1
WHERE t1.score >= `foo`.score) <= 5
GROUP BY team_id
ORDER BY `score` DESC;

SQL join with other table and adding a case

This following query is telling me how many sales was at the same day.
also how many new users, and credits.
This is my working query (it works great!):
SELECT Substring(purchase.`date`,1,10) AS `DayDate`,
Sum(Cast(Substring(purchase.`item`, 12) AS UNSIGNED)) AS `Credit`,
Count(1) AS `Sales`,
(SELECT Count(*) FROM enswitch_mobile_users WHERE Date(purchase.`date`) = Substring(enswitch_mobile_users.`creation_date`,1,10)) AS `New_users`
FROM (SELECT item, date
FROM enswitch_new_iphone_purchases WHERE `status`=1
UNION
SELECT item, date
FROM enswitch_new_android_purchases WHERE `status`=1) AS `purchase`
WHERE purchase.`date` >= :from_date AND purchase.`date` <= :to_date
GROUP BY `DayDate`
ORDER BY `DayDate` DESC
I am searching here in 3 tables.
enswitch_new_android_purchases enswitch_new_iphone_purchase
they both has item, user_id, status and date columns.
example for one entry:
date: 2012-08-01 16:24:30
item: xsalnx.sip.70
user_id: 1337
status: 1
Also pulling the mobile_users amount from enswitch_mobile_users(id, creation_date, mobile id, ...) and grouping with specific day date.
What I am trying to do is to add a test if the user who bought, or the new user is a tester. if so I want to ignore this data on my query.
I'm saving the testers on a table called:
enswitch_testing_devices (id, name, mobile_id).
And I can join the data with enswitch_mobile_users (mobile_id column).
So far I tried to make it work but had no luck..
How can I do this query ?
Try below - just added a clause when you get the users - get all the users except test. Now a sample data and structure table would help. (I think you can re-write the query.)
SELECT Substring(purchase.`date`,1,10) AS `DayDate`,
Sum(Cast(Substring(purchase.`item`, 12) AS UNSIGNED)) AS `Credit`,
Count(1) AS `Sales`,
(
SELECT Count(*)
FROM enswitch_mobile_users
WHERE
Date(purchase.`date`) = Substring(enswitch_mobile_users.`creation_date`,1,10)
AND enswitch_mobile_users.mobile_id NOT IN ( select mobile_id from enswitch_testing_devices WHERE 'is tester')
) AS `New_users`
FROM (SELECT item, date
FROM enswitch_new_iphone_purchases WHERE `status`=1
UNION
SELECT item, date
FROM enswitch_new_android_purchases WHERE `status`=1) AS `purchase`
WHERE purchase.`date` >= :from_date AND purchase.`date` <= :to_date
GROUP BY `DayDate`
ORDER BY `DayDate` DESC
I manage to SOLVE this issue.
If any one wondered.
function search_daily_sales($from_date, $to_date ,$show_testers)
{
// If not showing the testers
if ($show_testers === false)
{
$sql = "SELECT Substring(purchase.`date`,1,10) AS `DayDate`,
Sum(CASE WHEN td.mobile_id IS NULL
THEN Cast(Substring(purchase.`item`, 12) AS UNSIGNED)
ELSE '0' END) AS `Credit`,
Sum(CASE WHEN td.mobile_id IS NULL THEN '1' ELSE '0' END) AS `Sales`,
(SELECT Count(*) FROM enswitch_mobile_users
WHERE
Date(purchase.`date`) = Substring(enswitch_mobile_users.`creation_date`,1,10)
AND enswitch_mobile_users.`mobile_id` NOT IN (SELECT mobile_id FROM enswitch_testing_devices)) AS `New_users`,
MIN(CASE WHEN td.mobile_id IS NULL THEN '0' ELSE '1' END) AS `tester`
FROM (SELECT item, date, user_id
FROM enswitch_new_iphone_purchases WHERE `status`=1
UNION
SELECT item, date, user_id
FROM enswitch_new_android_purchases WHERE `status`=1) AS `purchase`
LEFT JOIN enswitch_mobile_users mu ON mu.id = purchase.user_id
LEFT JOIN enswitch_testing_devices td ON td.mobile_id = mu.mobile_id
WHERE purchase.`date` >= :from_date AND purchase.`date` <= :to_date
GROUP BY `DayDate`
ORDER BY `DayDate` DESC";
}
else
{
$sql = "SELECT Substring(purchase.`date`,1,10) AS `DayDate`,
Sum(Cast(Substring(purchase.`item`, 12) AS UNSIGNED)) AS `Credit`,
Count(1) AS `Sales`,
(SELECT Count(*) FROM enswitch_mobile_users WHERE Date(purchase.`date`) = Substring(enswitch_mobile_users.`creation_date`,1,10)) AS `New_users`
FROM (SELECT item, date
FROM enswitch_new_iphone_purchases WHERE `status`=1
UNION
SELECT item, date
FROM enswitch_new_android_purchases WHERE `status`=1) AS `purchase`
WHERE purchase.`date` >= :from_date AND purchase.`date` <= :to_date
GROUP BY `DayDate`
ORDER BY `DayDate` DESC";
}
$result = DB::query(Database::SELECT, $sql)->bind(':from_date', $from_date)->
bind(':to_date', $to_date)->execute();
return $result;
}

Limit the amount of results from mySQL conditionally?

Here is my query:
SELECT * FROM Photos WHERE Event_ID IN ($eventidstring)
I know I can limit the total amount of results from this query using LIMIT 5
I need the Limit the amount of results Per value in $eventidstring.
So if $eventidstring = 23,41,23*
*And there are 10 results WHERE Event_ID = 23, I want to limit this amount to 5. The same for all the other values in $eventidstring.
You may have some joy doing something similar to Oracle's RANK by PARITION in MySQL.
Sadly this feature is not available in MySQL though you can work around it using this method
Dump that in an inline view and then select those rows with rank <= 5;
Hence:
SELECT t.* FROM (
SELECT (
CASE Event_id
WHEN #curEventId
THEN #curRow := #curRow + 1
ELSE #curRow := 1 AND #curEventId := Event_Id END
) AS rank,
p.*
FROM Photos p INNER JOIN (SELECT #curRow := 0, #curEventId := '') r
ORDER BY p.Event_Id DESC
) t
WHERE t.rank <= 5 ORDER BY t.Event_Id asc;
Consider how you are going to 'choose' the top five by Event_Id too. You can always add in more after the ORDER BY p.Event_Id DESC to decide this.
I take it you're writing that query somewhere inside your PHP, so you need to split the $eventidstring into it's component values, form a SELECT for each and UNION all after the first one.
You sould do this with a loop of some sort, and concatenate the query strings in the loop...
If I understand correctly and you want to get five of each, you can use this:
(SELECT * FROM Photos WHERE Event_ID = 23 LIMIT 5)
UNION
(SELECT * FROM Photos WHERE Event_ID = 41 LIMIT 5)
UNION
(SELECT * FROM Photos WHERE Event_ID = ... LIMIT 5)
...
Maybe with a SELECT UNION but you need a new select for each value:
SELECT * FROM Photos WHERE Event_ID = 23 LIMIT 5
UNION SELECT * FROM Photos WHERE Event_ID = 41 LIMIT 5
UNION SELECT ...

Categories