I have this Query :
select
id_re_usr,
year(time) as AYear,
DAYOFYEAR(time) as ADay,
DATE_FORMAT(time, "%m-%d-%y") as date,
count(*) as TotalPerDay
from numrequest
where id_re_usr = "u1"
group by id_re_usr, AYear, ADay
order by AYear, ADay
it outputs something like
date TotalPerDay
------------------------
01-01-87 1
01-09-12 5
02-09-12 17
03-09-12 1
how can I find the maximum TotalPerDay without changing the current output by using php or changing the query.
I tried to do this and it works
$max=0;
while($row=mysql_fetch_array($results)){
if($max<$row['TotalPerDay']){ $max= $row['TotalPerDay'];}
}
but isn't there a direct way to do it?
if modifying the query the output should be
date TotalPerDay max
----------------------------------------
01-01-87 1 17
01-09-12 5 17
02-09-12 17 17
03-09-12 1 17
Join it to a second query of just the max count.. The inner-most queries on a per day basis (for the given user) a set of rows on count grouped per day. From that, the next outer does a select MAX() from that set to find and get only one record representing the highest day count... Since it will always return a single row, and joined to the original numRequest table it will be a Cartesian, but no problem since its only one record and you want that value on every returned row anyhow.
select
id_re_usr,
year(time) as AYear,
DAYOFYEAR(time) as ADay,
DATE_FORMAT(time, "%m-%d-%y") as date,
count(*) as TotalPerDay,
HighestCount.Max1 as HighestOneDayCount
from
numrequest,
( select max( CountsByDate.DayCount ) Max1
from ( select count(*) as DayCount
from numrequests nr
where nr.id_re_usr = "u1"
group by date( nr.time )) CountsByDate
) HighestCount
where
id_re_usr = "u1"
group by
id_re_usr,
AYear,
ADay
order by
AYear,
ADay
Related
I'm searching a very large database and would like to limit the rows returned based on this criteria.
My query looks like this
SELECT id,value,year FROM table WHERE value = '$formvariable'
All I really want is this:
If more than 250 rows are returned by the query show only the last 3 years of results ordered by year descending, limit 1000.
Otherwise 250 rows or less, show all.
You can try doing something like this:
SELECT * FROM YourTable
WHERE value = '$formvariable'
AND 250 >= (SELECT COUNT(*) FROM YourTable)
UNION ALL
SELECT * FROM YourTable t
WHERE value = '$formvariable'
AND 250 <= (SELECT COUNT(*) FROM YourTable)
AND t.year >= YEAR(DATE_ADD(curdate(), INTERVAL -3 YEAR))
ORDER BY t.year DESC
LIMIT 1000
In case there are less then 250 records, all will be selected in the first part of the UNION, and none will be selected from the second.
In case there are more, none will be selected from the first part, and only the 1000 first records of the past 3 years ordered by year will be selected.
I have a mySQL query that groups results by quiz attempt ID:
SELECT *
FROM quiz_log
WHERE archived = 0
GROUP BY quiz_attempt_id
ORDER BY quiz_attempt_id ASC
My question is how do I now count up the attempts in the by app_user_id. The app_user_id = 150 appears three times, so I need another column with the number 1 on the first line, 2 on the 3rd line and 3 on the 19th line.
You can use a correlated query:
SELECT t.*,
(SELECT count(distinct s.quiz_attempt_id) FROM quiz_log s
WHERE s.app_user_id = t.app_user_id
AND s.timestamp <= t.timestamp) as Your_Cnt
FROM quiz_log t
WHERE ....
I am trying to calculate the difference of values list coming from a database.
I would like to achieve it using php or mysql, but I do not know how to proceed.
I have a table named player_scores. One of its rows contains the goals scored.
Ex.
pl_date pl_scores
03/11/2014 18
02/11/2014 15
01/11/2014 10
I would like to echo the difference between the goals scored during the matches played in different dates.
Ex:
pl_date pl_scores diff
03/11/2014 18 +3
02/11/2014 15 +5
01/11/2014 10 no diff
How can I obtain the desired result?
You seem to want to compare a score against the score on a previous row.
Possibly simplest if done using a a sub query that gets the max pl_date that is less than the pl_date for the current row, then joining the results of that sub query back against the player_scores table to get the details for each date:-
SELECT ps1.pl_date, ps1.pl_scores, IF(ps2.pl_date IS NULL OR ps1.pl_scores = ps1.pl_scores, 'no diff', ps1.pl_scores - ps1.pl_scores) AS diff
FROM
(
SELECT ps1.pl_date, MAX(ps2.pl_date) prev_date
FROM player_scores ps1
LEFT OUTER JOIN player_scores ps2
ON ps1.pl_date > ps2.pl_date
GROUP BY ps1.pl_date
) sub0
INNER JOIN player_scores ps1
ON sub0.pl_date = ps1.pl_date
LEFT OUTER JOIN player_scores ps2
ON sub0.prev_date = ps2.pl_date
There are potentially other ways to do this (for example, using variables to work through the results of an ordered sub query, comparing each row with the value stored in the variable for the previous row)
SELECT score FROM TABLE WHERE DATE = TheDateYouWant
$score = $data['score'];
SELECT score FROM TABLE WHERE date = dateYouWant
$difference = $score - $data['score'];
Something like this?
You could use two queries, one to get the value to use in the comparison (in the example below is the smaller number of scores) and the second one to get the records with a dedicated column with the difference:
SELECT MIN(pl_scores);
SELECT pl_date, pl_scores, (pl_scores - minScore) as diff FROM player_scores;
Or, using a transaction (one query execution php side):
START TRANSACTION;
SELECT MIN(Importo) FROM Transazione INTO #min;
SELECT Importo, (Importo - #min) as diff FROM Transazione;
select *,
coalesce(
(SELECT concat(IF(t1.pl_scores>t2.pl_scores,'+',''),(t1.pl_scores-t2.pl_scores))
FROM tableX t2 WHERE t2.pl_date<t1.pl_date ORDER BY t2.pl_date DESC LIMIT 1)
, 'no data' ) as diff
FROM tableX t1
WHERE 1
order by t1.pl_date DESC
I want to count payment within selected date, but i can't figure it out how to do it.
Here is the example data from the my table
id starts_from payment_per_day
=======================================
1 2012-01-01 10,000.00
2 2012-01-15 10,500.00
3 2012-02-01 11,000.00
4 2012-02-15 11,500.00
5 2012-03-01 12,000.00
How do i count total payment from 2012-01-21 to 2012-02-20 ?
The total payment should be 338,500
from 2012-01-21 to 2012-01-31 = 11 days * 10,500
from 2012-02-01 to 2012-02-14 = 14 days * 11,000
from 2012-02-15 to 2012-02-20 = 6 days * 11,500
But if i do :
SELECT SUM(payment_per_day) as total FROM table
WHERE starts_from BETWEEN '2012-01-21' AND '2012-02-20'
the result is only 22,500
Any ideas ?
SELECT SUM(payment_per_day) as total FROM table
WHERE starts_from BETWEEN '2012-01-21' AND '2012-02-20';
I would first expand the range into the list of dates, then use the following query:
SELECT SUM(p1.payment_per_day)
FROM dates d
INNER JOIN payments p1 ON p1.starts_from <= d.date
LEFT JOIN payments p2 ON p2.starts_from <= d.date
AND p2.starts_from > p1.starts_from
WHERE p2.id IS NULL
You could obtain the list from the range with the help of a numbers table, like this:
SELECT DATE_ADD(#date_from, INTERVAL num DAY)
FROM numbers
WHERE num BETWEEN 0 AND DATEDIFF(#date_to, #date_from)
A numbers table is a thing worth having as it can be useful in many situations, so consider providing yourself with one. Here's a very simple script to create and initialise a numbers table:
CREATE TABLE numbers AS SELECT 0 AS num;
SET #ofs = (SELECT COUNT(*) FROM numbers); INSERT INTO numbers SELECT #ofs + num FROM numbers;
SET #ofs = (SELECT COUNT(*) FROM numbers); INSERT INTO numbers SELECT #ofs + num FROM numbers;
SET #ofs = (SELECT COUNT(*) FROM numbers); INSERT INTO numbers SELECT #ofs + num FROM numbers;
… /* repeat as necessary, each line doubles the number of rows in the table */
But, of course, you can use a loop instead.
Here's my complete testing environment on SQL Fiddle (for anyone to play with).
It seems that it is almost impossible to do query like that, counting total each day payment within selected date.
So i work around by selecting data from all starts_from dates until <= 2012-02-20 and then picking last starts_from date which is less than 2012-01-21 (that is 2012-01-15) in order to get payment_per_day 10,500.00
Thank you for viewing my question :)
Assuming this table is ordered by date
id | date | customer
3 | 2009-10-01| Frank
1 | 2010-10-11| Bob
4 | 2010-11-01| Mitchel
2 | 2010-11-02| Jim
I would like to make a query so that knowing ID = 4 the resulting rows are
$row[0]['id'] == 1 //previous
$row[1]['id'] == 4 //most recent/current
$row[2]['id'] == 2 //next
A mysql only solution would be best, but if there is an elegant php solution that would be cool as well.
As the table IS sorted by date column, you can run following queries to get it:
For previous row:
select * from tablename where `date` < (select `date` from tablename where id=4) order by `date` desc limit 1
For current row:
select * from tablename where id=4
For next row:
select * from tablename where `date` > (select `date` from tablename where id=4) order by `date` asc limit 1
Output: These three queries return the result (one by one) as following:
id date customer
1 2010-10-11 Bob
4 2010-11-01 Mitchel
2 2010-11-02 Jim
Since you are ordering by date, but basing the row you want the adjacent rows on id, your going to have to do 2 queries. The first to determine the date for the ID you have selected, the second to get the adjacent rows.
Step 1 - Get the date
Select date
FROM yourtable
WHERE id = 4
Step 2 - Get all the rows
SELECT *
FROM yourtable
WHERE date IN ( (select MAX( date ) from yourtable where date < $datefromquery1)
, $datefromquery1
, (select MIN( date ) from yourtable where date > $datefromquery1)
)
The LIMIT function can take two arguments, an offset and a number of rows to return. In your case, you want the offset to be (the number of rows with dates before the desired row) - 1, or in this case 2 - 1 = 1, and the number of rows to be three. So the SQL you want is
SELECT * FROM customers ORDER BY date ASC LIMIT 1,3;
and the number "1" will be the result of the query
SELECT COUNT(*)-1 FROM customers WHERE date > "2010-11-01";
I don't believe MySQL will let you use a subselect or function value as the argument of LIMIT, so you'll have to store that using PHP and construct the next query that way.