I use MariaDB and have a table where each row has a date and a score.
I want to first show the rows where the date is 3 days old or newer, sorted by the score - then show the rest (more than 3 days old) sorted by date.
Since my date is stored in unix time, it's fairly easy to have php calculate 3 days from before now and use that as my $scoreTimeLimit variable in the below:
Here are my two queries:
SELECT * FROM myTable WHERE myDate > $scoreTimeLimit ORDER BY myPopularityScore DESC
SELECT * FROM myTable WHERE myDate < $scoreTimeLimit ORDER BY myDate DESC
However, I would VERY much like to have only 1 query instead of two. Can it be done...?
This is a job for UNION.
SELECT * FROM (
SELECT 0 ord1, NOW() as ord2, *
FROM myTable WHERE myDate > NOW() - INTERVAL 3 DAY
UNION ALL
SELECT 1 ord1, myDate as ord2, *
FROM myTable WHERE myDate <= NOW() - INTERVAL 3 DAY
) a
ORDER BY ord1, ord2 DESC, myPopularityScore
The inner query gives you a single result set with a couple of extra columns added on to help you manage your sorting.
I have a table called payment it has date field, i have a customer called Mark who has been making payment every day for 3 years
Table: Payment
Fields: Name , Amountpaid, date
I want to display payment record made by mark every 3 month and also the total Amountpaid for 3 years
How i want the result to look like
First 3 months payment record table
total Amountpaid at the bottom of the table
second 3 months payment record table
total Amountpaid at the bottom of the table
Third 3 months payment record table
total Amountpaid at the bottom of the table
and so on for 3 years
Please do help out
It seems like you're looking for a SQL solution for this, but databases are for holding data, they aren't for formatting it into a report. To this end my advice would be: Don't try and do this in the database, do it in the front end code instead
It will be very simple to run a query like
SELECT * FROM payment WHERE
name = 'mark' and
`date` between date_sub(now(), interval 3 year) and now()
ORDER BY date
And then put the results into an HTML table usig a loop, and a variable that keeps track of the amount paid total. Every 3 months reset the variable. If you want MySQL to do a bit more data processing to help out you can do this:
SELECT * FROM
payment
INNER JOIN
(SELECT YEAR(`date`) + (QUARTER(`date`)/10) as qd, SUM(amountpaid) as qp FROM payment WHERE name = 'mark' GROUP BY YEAR(`date`), QUARTER(`date`)) qpt
ON
qpt.qd = YEAR(`date`) + (QUARTER(`date`)/10)
WHERE
name = 'mark' AND
`date` between date_sub(now(), interval 3 year) and now()
ORDER BY `date`
This will give all mark's data row by row and an extra two columns (that mostly repeat themselves over and over) showing the year and quarter (3 months) of the year like 2017.1, 2017.2, together with a sum of all payments made in that quarter. Formatting it in the front end now won't need a variable to keep a running total of the amount paid
This is about the limit of what you should do with formatting the data in the database (personal opinion). If, however, you're determined to have MySQL do pretty much all this, read on..
Ysth mentioned rollup, which is intended for summarising data.. such a solution would look like this:
SELECT
Name, `date`, SUM(amountpaid) as amountpaid
FROM
payment
WHERE
name = 'mark' AND
`date` between date_sub(now(), interval 3 year) and now()
GROUP BY
name,
YEAR(`date`) + (QUARTER(`date`)/10),
`date`
WITH ROLLUP
The only downside with this approach is you also get a totals row for all payments by mark. To suppress that, use grouping sets instead:
SELECT
Name, `date`, SUM(amountpaid) as amountpaid
FROM
payment
WHERE
name = 'mark' AND
`date` between date_sub(now(), interval 3 year) and now()
GROUP BY GROUPING SETS
(
(
name,
YEAR(`date`) + (QUARTER(`date`)/10),
`date`
),
(
name,
YEAR(`date`) + (QUARTER(`date`)/10)
)
)
You can use a group by on the year and month divided by 3 and truncated using floor
SELECT
EXTRACT(YEAR_MONTH FROM `date`),
SUM(`Amountpaid`)
FROM
`Payment`
WHERE
`Name` = 'Mark'
AND `date` >= DATE_SUB(NOW(), INTERVAL 3 YEAR)
GROUP BY
EXTRACT(YEAR FROM `date`),
FLOOR(EXTRACT(MONTH FROM `date`) / 3)
For the total you will need to iterate the result set and sum up the amounts paid, or if you want it as the final record you could do a UNION SELECT but this would be ineffecient, but for completeness it is below:
SELECT
EXTRACT(YEAR_MONTH FROM `date`),
SUM(`Amountpaid`)
FROM
`Payment`
WHERE
`Name` = 'Mark'
AND `date` >= DATE_SUB(NOW(), INTERVAL 3 YEAR)
GROUP BY
EXTRACT(YEAR FROM `date`),
FLOOR(EXTRACT(MONTH FROM `date`) / 3)
UNION SELECT
NULL,
SUM(`Amountpaid`)
FROM
`Payment`
WHERE
`Name` = 'Mark'
AND `date` >= DATE_SUB(NOW(), INTERVAL 3 YEAR)
This is for get summary per 3 months :
select year(date)*100+floor(month(date)/3) as period, sum(amountpaid)
from payment
where name = 'mark' and (date between '2014-01-01' and '2017-01-01')
group by year(date)*100+floor(month(date)/3)
order by period
And this is how to get summary 3 year :
select sum(amountpaid) from payment where name = 'mark' and (date between '2014-01-01' and '2017-01-01')
You can change the date between for your need
I have a question with mysql.
I have a table like records and records have a field registered_date which contains the dates. I want to select last n months but not before the current date. I must select the last date that registered_date contains.
registered_date
2015-05-30
2015-05-29
2015-05-28
2015-05-27
...
and we are in july. The last date is 2015-05-30. I want to select last 3 months before the 2015-05-30.
I tried to like these:
.... where registered_date > DATE_SUB(now(), INTERVAL 6 MONTH)
and
registered_Date between now() - interval 30 day and now()
Thank you.
You need to find the biggest date and then select three months before that:
select t.*
from table t cross join
(select max(registered_date) as maxrd from table t) m
where t.registered_date >= maxrd - interval 3 month;
Did you try like this
SELECT * FROM table WHERE registered_date >= now()-interval 3 month;
I have a mysql table with the following fields
Name | Email | Date | Status
I want to extract the records where date range is between 30 days
Assume today is 2014/12/9
ie. date values are
2014/11/25
2014/12/2
2014/12/1
2014/10/25
2014/11/9
I need the o/p as (the number of days should be with in 30 days from the db date to today date)
2014/11/25
2014/12/2
2014/12/1
2014/11/9
I want to extract records those have the interval of less than 30 days from the date in the db.
Yes. I want to fetch the record between 2 days. For this I used this query
SELECT * FROM tbl_jobboard WHERE dtDate <= ( dtDate +30 )
But it is not working.
How to write the select query?
USE DATE_SUB like this:
SELECT * FROM table1
WHERE `date` BETWEEN DATE_SUB(CURDATE(),INTERVAL 30 DAY) AND CURDATE()
Working Fiddle Demo: http://sqlfiddle.com/#!2/6344f2/1
use following query
select * from table_Name t where t.date<=now() and t.date>=DATE_SUB(now(),
INTERVAL 31 DAY)
I have fee records in my database table. I want to fetch 3 months back records of the fees in database. I am using:
SELECT * FROM fee_challans
WHERE student_id = 630
AND STATUS = 'un-paid'
AND DATE_FORMAT( fee_date, '%Y-%m-%d' ) - INTERVAL 2 MONTH
This query that I searched and found on google.
You forgot to compare your column to something...
SELECT * FROM fee_challans
WHERE student_id = 630
AND STATUS = 'un-paid'
AND fee_date >= CURDATE() - INTERVAL 3 MONTH;
And if your fee_date column is of type date, datetime or timestamp, date_format() is not necessary.