I have a table as:
date passed failed subject
2015-2-1 2 1 maths
2015-2-1 3 2 cs
2015-3-1 1 2 maths
2015-12-1 2 1 maths
I have a form to select the start date and end date.
for eg:If I select startdate = 2015-2-1 and enddate=2015-3-1
my output should be:
date passed failed
2015-2-1 5 3
2015-3-1 1 2
output should contain the total no of passed and failed (irrespective of subjects) for same months as shown above.
This is the query which I used:
startdate=2015-2-1 and enddate=2015-3-1
SELECT SUM(passed) ,SUM(failed) FROM student_log WHERE
(DATE(`date`)='2015-2-1')
union
SELECT SUM(passed) ,SUM(failed) FROM student_log WHERE
(DATE(`date`)='2015-3-1')
It works fine But if my end date is December I should repeat my union query till December...
Please suggest an alternative.
What about:
SELECT SUM(passed), SUM(failed), DATE(`date`)
FROM student_log
WHERE DATE(`date`) >= '2015-2-1' AND DATE(`date`) <= '2015-3-1'
GROUP BY DATE(`date`);
This would find all tests between two dates and give you a count from each day.
You dont need separate queries or join or union for this
SELECT SUM(`pass`) as total_pass, SUM(`fail`) as total_fail
FROM pass_fail
WHERE (`date` = '2015-2-1' or `date` = '2015-3-1' )
GROUP BY `date`
Output
Refer Group By
this query :
Select date,sum (passed),sum(failed) from Results group by date
returns the following results for me :
date passed failed
2015-02-01 5 3
2015-03-01 1 2
2015-12-01 2 1
In other words: The group by clause will display the data per Month as you need it.
Related
create table link : https://drive.google.com/file/d/1EEqpW2Y8UkplfQcp_fw0j2byXAxBQXOW/view?usp=sharing
I have a query
SELECT
DATE_FORMAT(seized_date,'%Y-%m') as 'Seized Date',
sum(case when seized_remarks = 'Temporary Seized' then 1 else 0 end) AS seized,
sum(case when (DATE_FORMAT(release_date, '%Y-%m') BETWEEN '2021-01' AND '2021-07') then 1 else 0 end) AS released,
sum(case when (DATE_FORMAT(stock_return_date, '%Y-%m') BETWEEN '2021-01' AND '2021-07') then 1 else 0 end) AS stock_return
FROM mahindra
where
(DATE_FORMAT(seized_date, '%Y-%m') BETWEEN '2021-01' AND '2021-07')
GROUP BY DATE_FORMAT(seized_date,'%Y-%m')
which gives result as
Date Seized Release Stock Return
2021-01 1 0 0
2021-03 1 0 0
2021-04 1 0 0
2021-05 5 1 0
2021-06 6 0 1
2021-07 2 0 0
here i didn't get the result of february 2021. I want to get the result of all months between this two dates even if the seized_date does not exist
Looks like you need in something like
SELECT
dates.`Seized Date`,
COALESCE(SUM(mahindra.seized_remarks = 'Temporary Seized'), 0) AS seized,
COALESCE(COUNT(mahindra.release_date), 0) AS released,
COALESCE(COUNT(mahindra.stock_return_date), 0) AS stock_return
FROM ( SELECT '2021-01' `Seized Date` UNION ALL
SELECT '2021-02' UNION ALL
SELECT '2021-03' UNION ALL
SELECT '2021-04' UNION ALL
SELECT '2021-05' UNION ALL
SELECT '2021-06' UNION ALL
SELECT '2021-07' ) dates
LEFT JOIN mahindra ON DATE_FORMAT(mahindra.seized_date, '%Y-%m') = dates.`Seized Date`
GROUP BY dates.`Seized Date`
As #Akina says, if the seized_date value does not exist anywhere in your table, you cannot expect it to be present in your results at all.
You need to create a column containing all required dates and then you can do something like perform a join onto that column.
Here's an example of how I might do it.
SELECT TO_CHAR(DATEADD('MONTH', -n, (CURRENT_DATE+1)),'YYYY-MM') AS seized_date
FROM (
SELECT ROW_NUMBER() OVER () AS n
FROM mahindra LIMIT 10
)
ORDER BY seized_date DESC
This is creates the following output.
Code explanation:
The inner query is based on a window function.
The window function itself is simple. We're basically telling the computer to assign a value of 10 to n. To a human, "10" is a numeric value assigned to a specific thing or count of things (eg the temperature is 10 degrees, or I have 10 apples), but to the processor/computer, it doesn't mean much on its own. At least not in our scenario. So we simply tell the processor to count some rows ROW_NUMBER and when it finds 10 rows, that's what 10 looks like. You can use LIMIT to make this greater or fewer than 10 months.
In the outer query we just take today's date CURRENT_DATE and subtract n months from it as in (DATEADD('MONTH', -n, (CURRENT_DATE+1).
In our case, n is 10 months.
Now you have a column of dates, formatted as you per your requirements YYYY-MM.
You can write the query such that you LEFT JOIN your precessed data set to these dates on their corresponding values.
The reason why this is a good way of doing things is that you don't have to manually enter any dates or use a UNION join. You let the window function do the work for you, meaning you can go back in time as far as you need/or want very easily by changing the LIMIT value. This allows for greater efficiency in the event where you need to go back over multiple years, for example.
I'm developping a dashboard for a restaurant/bar.
I want to manipulate the date , so for example:
If they sell something at 02 january ,01h30 .
This amount should be added to the amount of the 1st January and not to the amount of the 2nd January.
So basically on the next day from 00h00 until 03h59, the amount that they sell, should be added to the previous date.
At the moment my SQL query just displays both dates but I want it grouped in 1 date. If this isn't possible with SQL, I have my dashboard in PHP, so I can eventually manipulate it in PHP if anyone could provide me that info.
My query
select CONVERT(CHAR(10), receiptdatetime, 120), datename(DW,receiptdatetime),
sum(rld.NetAmount), count(rl.ReceiptId)
from receipt r, receiptline rl, vw_ReceiptLineDetail rld
where rl.ReceiptId = r.ReceiptId and
rl.ModifiedKind != 300
and rld.ReceiptLineId = rl.ReceiptLineId and
receiptdatetime <= DATEADD(HOUR,4,DATEADD(DAY,1, '01/01/2018'))
and receiptdatetime >= DATEADD(HOUR,4,'01/01/2018')
group by CONVERT(CHAR(10), receiptdatetime, 120), datename(DW, receiptdatetime)
order by 1
So the current output is like this (shortened):
Date Amount
1 01/01/2018 100
2 02/01/2018 20
But I want it like this
Date Amount
1 01/01/2018 120
You can use this query and work with dates as you want
here is you first query that gives you that result
select CONVERT(CHAR(10), receiptdatetime, 120), datename(DW,receiptdatetime),
sum(rld.NetAmount), count(rl.ReceiptId)
from receipt r, receiptline rl, vw_ReceiptLineDetail rld
where rl.ReceiptId = r.ReceiptId and
rl.ModifiedKind != 300
and rld.ReceiptLineId = rl.ReceiptLineId and
receiptdatetime <= DATEADD(HOUR,4,DATEADD(DAY,1, '01/01/2018'))
and receiptdatetime >= DATEADD(HOUR,4,'01/01/2018')
group by CONVERT(CHAR(10), receiptdatetime, 120), datename(DW, receiptdatetime)
order by 1
you can use this result as a first select with this :
With CTE as
(
select CONVERT(CHAR(10), receiptdatetime, 120), datename(DW,receiptdatetime),
sum(rld.NetAmount), count(rl.ReceiptId)
from receipt r, receiptline rl, vw_ReceiptLineDetail rld
where rl.ReceiptId = r.ReceiptId and
rl.ModifiedKind != 300
and rld.ReceiptLineId = rl.ReceiptLineId and
receiptdatetime <= DATEADD(HOUR,4,DATEADD(DAY,1, '01/01/2018'))
and receiptdatetime >= DATEADD(HOUR,4,'01/01/2018')
group by CONVERT(CHAR(10), receiptdatetime, 120), datename(DW, receiptdatetime)
order by 1
)
so like this you have the result stored on a table called CTE
NOw i don't have the data so i will create my owne Variable table to store the result that you got from first query you can use your CTE tabale as a source instade of #Table
Declare #Table table (
id int,
dates date,
amout int
)
insert into #Table
select 1 , '2018-01-01' , 100 union
select 2 , '2018-01-02' , 20 union
select 2 , '2018-02-02' , 200 union
select 2 , '2018-01-03' , 20 union
select 2 , '2018-01-04' , 20
now to get the Amout with the result that you want here is the query to use
you do the select from CTE :
select sum(amout) as Amout from #Table
where dates between '2018-01-01' and '2018-01-04'
Result :
Amout
160
now you will use that result and union it with you table to get the ID that you want and the date that you want and i thing you should convert the last table date into nvarchar(50) so you will have this result
1- when you do the whole month
ID Date Amout
1 2018-01 160
2- when you do by timeframe
ID Date Amout
1 '2018-01-01 2018-01-14' 160
you can start by hardcoding the ID and Date as you want and union is to the result Amout that you get from the query
or you can do variables to configure the ID and date that you want to show with the Amout
thanks if you ahve any questions i'm here i have done the test on my local and it works and i hope that this is what you need :)
use the :
;With CTE as ( select (RowCount() Over (Partition by Date order by id) row_count) , date, amout
from tables and where conditions
Then on the select Add the amount that have the same Date into each others
selecting from CTE table
if you want to Add the Amounts of all day on the same month then select Only Year and Month on Date column then do the partition by over this Date
I have an example
id projectid date
1 2 2015-04-19
2 2 2015-04-19
3 2 2015-04-19
4 2 2015-04-19
5 2 2015-04-21
6 2 2015-04-21
7 2 2015-04-21
8 2 2015-04-22
9 2 2015-04-22
10 2 2015-04-22
I want to show next upcoming stored date using 2015-04-19 date, i.e next date is 2015-04-21, using mysql query
id projectid date
5 2 2015-04-21
6 2 2015-04-21
7 2 2015-04-21
I have written query for you. I hope it will resolve your problem.
QUERY
SELECT * FROM table
WHERE `date` = (SELECT `date` FROM table
WHERE `date`>'2015-04-19' ORDER BY `date` ASC LIMIT 1);
Use DateAdd Function in Select Statement like below
DATEADD(d,1,(CASE table.date as Date))
Basically to display next date older than 2015-04-19 from your database, this should be enough:
SELECT * FROM table WHERE date > '2015-04-19' ORDER BY date ASC LIMIT 1
SELECT * FROM table WHERE date > '2015-04-19' ORDER BY date LIMIT 1
UPDATE
You wrote that you want to show next upcoming stored date, but looking at your example output and your comment it looks like you want to get all records with the next date.
SELECT * FROM table WHERE date=(
SELECT date FROM table WHERE date > '2015-04-19' ORDER BY date LIMIT 1
)
SQL Fiffle example, use it as a copy paste solution.
Sub query will return the next date from which results will come according to that date only.
SELECT * FROM tableName WHERE date=("SELECT date FROM table WHERE date > '2015-04-19' ORDER BY date LIMIT 1")
I have a scenario where I need to pull up delivery dates based on a table below (Example)
job_id | delivery_date
1 | 2013-01-12
2 | 2013-01-25
3 | 2013-02-15
What I'm trying to do is show the user all the delivery dates that start with the earliest (in this case it would be 2013-01-12) and add an another 21 days to that. Basically, the output I would expect it to show of course, the earliest date being the starting date 2013-01-12 and 2013-01-25. The dates past the February date are of no importance since they're not in my 21 date range. If it were a 5 day range, for example, then of course 2013-01-25 would not be included and only the earliest date would appear.
Here is main SQL clause I have which only shows jobs starting this year forward:
SELECT date, delivery_date
FROM `job_sheet`
WHERE print_status IS NULL
AND job_sheet.date>'2013-01-01'
Is it possible to accomplish this with 1 SQL query, or must I go with a mix of PHP as well?
You can use the following:
select *
from job_sheet
where print_status IS NULL
and delivery_date >= (select min(delivery_date)
from job_sheet)
and delivery_date <= (select date_add(min(delivery_date), interval 21 day)
from job_sheet)
See SQL Fiddle with Demo
If you are worried about the dates not being correct, if you use a query then it might be best to pass in the start date to your query, then add 21 days to get the end date. Similar to this:
set #a='2013-01-01';
select *
from job_sheet
where delivery_date >= #a
and delivery_date <= date_add(#a, interval 21 day)
See SQL Fiddle with Demo
SELECT date,
delivery_date
FROM job_sheet
WHERE print_status IS NULL
AND job_sheet.date BETWEEN (SELECT MIN(date) FROM job_sheet) AND
(SELECT MIN(date) FROM job_sheet) + INTERVAL 21 DAY
SELECT j.job_id
, j.delivery_date
FROM `job_sheet` j
JOIN ( SELECT MIN(d.delivery_date) AS earliest_date
FROM `job_sheet` d
WHERE d.delivery_date >= '2013-01-01'
) e
ON j.delivery_date >= e.earliest_date
AND j.delivery_date < DATE_ADD(e.earliest_date, INTERVAL 22 DAY)
AND j.print_status IS NULL
ORDER BY j.delivery_date
(The original query has a predicate on job_sheet.date; the query above references the d.delivery_date... change that if it is supposed to be referencing the date column instaed.)
If the intent is to only show delivery_date values from today forward, then change the literal '2013-01-01' to an expression that returns the current date, e.g. DATE(NOW())
i have the following statement:
SELECT
count(rs.rsc_id) as counter
FROM shots as rs
where rsc_rs_id = 345354
AND YEAR(rs.timestamp) = YEAR(DATE_SUB(CURDATE(), INTERVAL 6 MONTH))
GROUP BY DATE_FORMAT(rs.timestamp,'%Y%m')
rs.timestamp is a unix timestamp
Output would be like for each row / month a numeric like '28'
It Works fine, but if i have inconsistent data, like only for the past three month (not for all six month), i get no return from my Database. I would like to have every time there is not data for this month, 0 returned...
any suggestion?
i thought about some case statements, but this seems not so good...
thanks!!
For only 6 months, a date table seems unnecessary, although this looks complicated (it really isn't!)
SELECT DATE_FORMAT(N.PivotDate,'%Y%m'), count(rs.rsc_id) as counter
FROM (
select ADDDATE(CURDATE(), INTERVAL N MONTH) PivotDate
FROM (
select 0 N union all
select 1 union all
select 2 union all
select 3 union all
select 4 union all
select 5 union all
select 6) N) N
LEFT JOIN shots as rs
ON rsc_rs_id = 345354
AND DATE_FORMAT(N.PivotDate,'%Y%m')=DATE_FORMAT(FROM_UNIXTIME(rs.timestamp),'%Y%m')
GROUP BY DATE_FORMAT(N.PivotDate,'%Y%m')
In such cases it's common to use a table of dates with all dates (e.g. from 1/1/1970 to 31/12/2999) and LEFT JOIN your data to that table.
See an example in the answer here: mysql joins tables creating missing dates
If you create a dates table you can use:
SELECT
DATE_FORMAT(d.date,'%Y%m') AS `month`, count(rs.rsc_id) AS `counter`
FROM dates d
LEFT JOIN shots as rs
ON d.date = FROM_UNIXTIME(rs.timestamp)
AND rs.rsc_rs_id = 345354
WHERE d.date > DATE_SUB(CURDATE(), INTERVAL 5 MONTH)
AND d.date < CURDATE()
GROUP BY DATE_FORMAT(d.date,'%Y%m');