Mysql query for matching month and year - php

I have form with 4 fields namely(start month, start year, end month, end year)
and MySQL table structure is like id, customer id, amount, month, year
Now, I need to display the rows with matching condition as between the start month and year and end month and year.
I tried this query
select id,customer id,concat(month,'-',year) as d1 from payroll where
empid='$_POST[emp_id]' and (STR_TO_DATE(d1,'%m-%Y') between
STR_TO_DATE('$_POST[fmonth]-$_POST[fyear]','%m-%Y') and
STR_TO_DATE('$_POST[tmonth]-$_POST[tyear]','%m-%Y'))
Please advise....

Assuming the columns year and month and the 4 form fields are integers, this would work:
SELECT id
, customer id
, CONCAT(month, '-', year) AS d1
FROM payroll
WHERE empid = '$_POST[emp_id]'
AND (year, month) >= ( '$_POST[fyear]', '$_POST[fmonth]' )
AND (year, month) <= ( '$_POST[tmonth]', '$_POST[tyear]' )
You should probably take care of those $_POST[] before sending them to the database for security reasons (SQL injection).
A compound index on (empid, year, month) would help performance.

Related

SQL query date range saved in 2 columns

I have a table (Hire Rates) which contains multiple records. I'm trying to find records based on a date query but cannot get it to work correctly.
Essentially I am looking for records that contain a date between two dates. If my query date is "2021-08-15", it should return the third row (3000) as the query date falls between the two dates.
It is mostly working for me, except if the query date is equal to the start date or end date - in that case it doesn't return any result.
Table
startDate
endDate
hireRate
2021-01-01
2021-03-05
2350
2021-03-06
2021-04-08
2890
2021-04-09
2021-09-15
3000
Query
$sql = "SELECT rate, currencyID FROM hire_rates WHERE status = '1' AND NOT (startDate >= '$queryDate' OR endDate <= '$queryDate')
Try adding 'between' condition.
Like
select rate, currencyId from hire_rates where states =1 and not (cast($queryDate as DATE) between cast(startDate As DATE) and cast(endDate AS DATE) )
You would pass in the date you care about as a parameter. Then you can use between (based on your description of the logic):
SELECT rate, currencyID
FROM hire_rates
WHERE status = 1 AND
? BETWEEN startDate AND endDate;
Where ? is a parameter for the date you are passing in.
For 2021-08-15, you can write:
WHERE status = 1 AND
'2021-08-15' BETWEEN startDate AND endDate;
If you want the current date, you can actually get that from the database:
SELECT rate, currencyID
FROM hire_rates
WHERE status = 1 AND
curdate() BETWEEN startDate AND endDate;
Just try this then, `$sql = SELECT hireRate FROM hire_rate WHERE startDate<= '$queryDate' and endDate >= '$queryDate'

query to calculate the total salary for each month

I have a table with 4 fields as follows
I want an Sql query to calculate a total salary for each month, where the result will be as follows
Do you just want group by and sum()?
select sum(salary) salary, month
from mytable
group by month

Average day values of last month as a SQL statement

I got a table with two columns, timestamp (like '1405184196') and value.
I've saved some measured values.
$day= time()-84600;
$result = mysql_query('SELECT timestamp, value FROM table WHERE timestamp >= "'.$day.'" ORDER BY timestamp ASC');
This is how I get all values for the last 24h.
But is it possible to get average day values for the last month with a SQL statement or do I have to select all values of the last month and calculate the average of each day via PHP?
Several issues with Anish's answer:
1) This won't work if date+time is being stored in the timestamp field.
2) It assumes the OP means last month i.e June, May etc and not the last say 30 days.
This solves those issues:
SELECT DATE(`timestamp`) as `timestamp`, AVG(value)
FROM table
WHERE `timestamp` >= CURDATE() - INTERVAL 1 MONTH
GROUP BY DATE(`timestamp)
EDIT
Since the timestamp is a unix timestamp and the OP would like a calendar month:
SELECT DATE(FROM_UNIX(`timestamp`)) as `timestamp`, AVG(value)
FROM table
WHERE MONTH(FROM_UNIX(`timestamp`)) = MONTH(NOW() - 1)
GROUP BY DATE(FROM_UNIX(`timestamp))
You can do this:-
SELECT timestamp, AVG(value)
FROM table
GROUP BY timestamp
HAVING MONTH(timestamp) = MONTH(NOW()) - 1;
This query calculates average for last month.
DEMO

MYSQL select query with multiple tables

I have 2 tables,
prices (pcode, date, priceperweek)
1 record covers 1 week
booked (pcode, date)
1 record = 1 day, because shortbreaks are available
And a form consists of 3 fields
startdate
flexibility (+/- 1/2/3 weeks)
duration (3 / 4 / 5 / 6 / 7 / 14)).
The below query should be selecting prices & dates and checking to see if the selected start date appears in the prices table and that each day from the startdate doesn't appear in the bookings table.
SELECT SUM(priceperweek) AS `ppw`, prices.date AS `startdate`
FROM `prices` LEFT JOIN `booked` ON prices.pcode=booked.pcode
WHERE prices.pcode='A2CD59GH'
AND (prices.date IN ('20131221', '20131228')
AND booked.date NOT IN ('20131221', '20131222', '20131223',
'20131224', '20131225', '20131226', '20131227', '20131228',
'20131229', '20131230', '20131231', '20140101', '20140102',
'20140103')
)
OR (prices.date IN ('20131214', '20131221')
AND booked.date NOT IN ('20131214', '20131215', '20131216',
'20131217',
'20131218', '20131219', '20131220', '20131221', '20131222',
'20131223', '20131224', '20131225', '20131226', '20131227')
)
OR (prices.date IN ('20131228', '20140104') AND booked.date NOT IN
('20131228', '20131229', '20131230', '20131231', '20140101',
'20140102', '20140103', '20140104', '20140105', '20140106',
'20140107', '20140108', '20140109', '20140110')
)
GROUP BY prices.date
ORDER BY prices.date ASC
VALUES GIVEN TO QUERY...
startdate = 20131221
duration = 14
property = A2CD59GH
plusminus = 1
My problem is that this query returns records even if some of the dates in a range appear in the "bookings" table AND the ppw value is alot more than i would have expected.
The reason for using SUM(ppw) is when a duration of 14 is specified the price will sum both weeks together.
Thanks for any help on this
The problem with your approach is that the startdate will only be filtered from the results if every single record in the booked table for the given pcode falls within the booking period. Obviously this won't be the case if the property has been booked on some other date.
I'd suggest performing an anti-join along the following lines:
SELECT t.date, SUM(prices.priceperweek) FROM prices JOIN (
SELECT prices.date
FROM prices LEFT JOIN booked
ON booked.pcode = prices.pcode
AND booked.date BETWEEN prices.date
AND prices.date + INTERVAL 14 DAY
WHERE booked.pcode IS NULL
AND prices.pcode = 'A2CD59GH'
AND prices.date BETWEEN '20131221' - INTERVAL 1 WEEK
AND '20131221' + INTERVAL 2 WEEK
) t ON prices.date BETWEEN t.date AND t.date + INTERVAL 13 DAY
GROUP BY t.date

update database sum monthly based on signup date

Need help writing a function for database. I want to keep track of the total cost of member orders each month based on their signup date. So if someone signed up in the middle of the month, the function should add 30 days to their signup date and sum the sales whithin that period and place in database. Then display on user page. Using mysql functions (not PDO or mysqli for now).
Something like:
<?php
$query = ("SELECT SUM(cost) FROM memberOrders WHERE
memberNumber='$memberNumber' GROUP BY signupdate+30days");
?>
But it can't be just 30 days...it should be +30, +60, +90...That's the part I'm stuck on. Thanks!
calculate the start/end date in PHP and make use of a subquery:
SELECT SUM(cost) FROM
(Select cost, membernumber from memberOrders WHERE
memberNumber='$memberNumber' and date >= '$startdate' and date <= '$enddate'
GROUP BY substr(date, 7))
GRoup by membernumber
Assuming you have both the signup date and order date in MemberOrders, the following will return all months with orders:
SELECT datediff(orderdate, signupdate, interval month) as MonthsAfter,
SUM(cost) as MonthCost
FROM memberOrders
WHERE memberNumber='$memberNumber'
GROUP BY datediff(orderdate, signupdate, interval month)
If you have all months having 30-days, you can do:
SELECT floor(datediff(orderdate, signupdate, interval day)/30) as Months,
SUM(cost) as MonthCost
FROM memberOrders
WHERE memberNumber='$memberNumber'
GROUP BY floor(datediff(orderdate, signupdate, interval day)/30)
Note: both of these assign "0" to the first month after signup. Add +1 if you want to start at 1.

Categories