MySQL - Getting data for week ahead - php

I have this sql query:
SELECT
"bookings"."customerID",
"bookings"."arrivalDate",
"bookings"."leavingDate",
"bookings"."bookingID",
"bookings"."pickup",
"bookings"."dropoff",
"bookings"."locationID",
"locations"."locationName",
"customers"."customerName"
FROM
"bookings"
LEFT JOIN "customers" ON
"bookings"."customerID" = "customers"."customerID"
LEFT JOIN "locations" ON
"bookings"."locationID" = "locations"."locationID"
WHERE (
"bookings"."arrivalDate" BETWEEN '2014-11-15' AND '2014-11-22'
)
What i'm hoping to get is all the bookings for the week ahead. Sorted by oldest first. Just cant get it to work!

SELECT
b.customerID,
b.arrivalDate,
b.leavingDate,
b.bookingID,
b.pickup,
b.dropoff,
b.locationID,
l.locationName,
c.customerName
FROM
bookings b
LEFT JOIN customers c
ON b.customerID = c.customerID
LEFT JOIN locations l
ON b.locationID = l.locationID
WHERE
b.arrivalDate > curdate()
AND b.arrivalDate <= date_add( curdate(), INTERVAL 7 DAY )
order by
b.leavingDate DESC
I updated to utilize aliases vs long table name references. Also, the where clause to make use of the current date and 7 days forward to get the week ahead so it is not hard-referenced. You could additionally adjust in case you wanted the query always to be based on a Sat or Sun of a given week.
As for the sorting by the "oldest" first... oldest in what way... just change the order by clause. I am GUESSING your intent was on the date leaving out... So by that column DESCENDING would put the oldest LEAVING item at the top of the list.

Related

get monthly record of employees in one query using mysql

I am using this query for getting monthly record of employees those are present and absent.
However i am getting the result for one employee by using this query but for all employees it doesn't seems to work.
SELECT
m.emp_id AS `Empid`,
d.dt AS `AbsentDate`,
(CASE
WHEN p.punch_status IS NULL THEN 'A'
ELSE p.punch_status
END) s
FROM
(SELECT
DATE(t.added_date) AS dt
FROM
pmc_attendance t
WHERE
DATE(t.added_date) >= '2018-08-01'
AND DATE(t.added_date) < DATE_ADD('2018-08-31', INTERVAL 1 DAY)
GROUP BY DATE(t.added_date)
ORDER BY DATE(t.added_date)) d
CROSS JOIN
tbl_admin_users m
LEFT JOIN
pmc_attendance p ON DATE(p.added_date) >= d.dt
AND DATE(p.added_date) < d.dt + INTERVAL 1 DAY
AND p.emp_id = m.emp_id
WHERE
p.emp_id IS NULL AND m.emp_id = '000838'
GROUP BY d.dt
ORDER BY m.emp_id , d.dt
I am using two tables 1. tbl_admin_users- employee data stored 2. pmc_attendance- present records of employees.
in query if i have passed the and m.emp_id='000838' it works fines but i want to show all records for all employees. any suggestions how i can optimize this query.
There are a couple of ways to structure this query. I can see what yuo are doing, and I think the only issue is with your group by clauses. You dont need them as everything should be distinct. Your status will always be 'A' as you are only getting rows where there is no punch for the employee for the day, so you can also take out the case statement.
SELECT
m.emp_id AS Empid,
d.dt AS AbsentDate,
'A' s
FROM
(
SELECT distinct DATE(t.added_date) AS dt
FROM pmc_attendance t
WHERE t.added_date >= '2018-08-01' AND DATE(t.added_date) < DATE_ADD('2018-08-31', INTERVAL 1 DAY)
) d
CROSS JOIN tbl_admin_users m
LEFT JOIN pmc_attendance p ON p.emp_id = m.emp_id and DATE(p.added_date) >= d.dt AND DATE(p.added_date) < d.dt + INTERVAL 1 DAY
WHERE p.emp_id IS NULL
ORDER BY m.emp_id , d.dt
If you want to include both present and absent, you would need to put your case statement back in, and remove your check WHERE p.emp_id IS NULL
If you have multiple punchs for the day, then you need to resolve it down to a single entry with a MIN/MAX so you only get one row per person per day, and add back in your group by Emp_ID, d.dt

Min value from Database in MySQL

Am trying to find the min value from past 30 days, in my table there is one entry for every day, am using this query
SELECT MIN(low), date, low
FROM historical_data
WHERE name = 'bitcoin'
ORDER BY STR_TO_DATE(date,'%d-%m-%Y') DESC
LIMIT 7
But this value not returing the correct value. The structure of my table is
Table structure
And table data which is store is like this
Table data style
Now what i need is to get the minimum low value. But my query not working it give me wrong value which even did not exist in table as well.
Updates:
Here is my updated Table Structure.
enter image description here
And here is my data in this table which look like this
enter image description here
Now if you look at the data, i want to check the name of token omisego and fatch the low value from past 7 days which will be from 2017-12-25 to 2017-12-19
and in this cast the low value is 9.67, but my current query and the query suggested by my some member did not brings the right answer.
Update 2:
http://rextester.com/TDBSV28042
Here it is, basically i have more then 1400 coins and token historical data, which means that there will me more then 1400 entries for same date like 2017-12-25 but having different name, total i have more then 650000 records. so every date have many entries with different names.
To get the lowest row per group you could use following
SELECT a.*
FROM historical_data a
LEFT JOIN historical_data b ON a.name = b.name
AND a.low > b.low
WHERE b.name IS NULL
AND DATE(a.date) >= '2017-12-19' AND DATE(a.date) <= '2017-12-25'
AND a.name = 'omisego'
or
SELECT a.*
FROM historical_data a
JOIN (
SELECT name,MIN(low) low
FROM historical_data
GROUP BY name
) b USING(name,low)
WHERE DATE(a.date) >= '2017-12-19' AND DATE(a.date) <= '2017-12-25'
AND a.name = 'omisego'
DEMO
For last 30 day of 7 days or n days you could write above query as
SELECT a.*, DATE(a.`date`)
FROM historical_data2 a
LEFT JOIN historical_data2 b ON a.name = b.name
AND DATE(b.`date`) >= CURRENT_DATE() - INTERVAL 30 DAY
AND DATE(b.`date`) <= CURRENT_DATE()
AND a.low > b.low
WHERE b.name IS NULL
AND a.name = 'omisego'
AND DATE(a.`date`) >= CURRENT_DATE() - INTERVAL 30 DAY
AND DATE(a.`date`) <= CURRENT_DATE()
;
DEMO
But note it may return more than one records where low value is same, to choose 1 row among these you have specify another criteria to on different attribute
Consider grouping the same and running the clauses
SELECT name, date, MIN(low)
FROM historical_data
GROUP BY name
HAVING name = 'bitcoin'
AND STR_TO_DATE(date, '%M %d,%Y') > DATE_SUB(NOW(), INTERVAL 30 DAY);
Given the structure, the above query should get you your results.
// Try this code ..
SELECT MIN(`date`) AS date1,low
FROM historical_data
WHERE `date` BETWEEN now() - interval 1 month
AND now() ORDER by low ASC;

Get Count 0 instead of NULL MySQL Query

I've got a query that counts the number of posts in a month with a certain tag, but obviously my WHERE won't return anything if there are no posts. The problem with that, I have overlayed on the chart another query that shows ALL posts, not just the ones who meet these WHERE conditions. The second query will typically have a result for every month. How can I get this query to return zero if the result is null? I've read a few of the answers here, but can't quite figure it out.
SELECT MONTHNAME(post_time) AS month,
COALESCE(Count(distinct p.post_id), 0) AS count
FROM post.p
INNER JOIN post_tag_map t ON ( p.post_id = t.knote_id )
WHERE t.post_id IN (23,24,49,54)
/*these numbers are actually a variable, this is just an example*/
AND p.post_time >= (CURDATE() - INTERVAL 1 YEAR)
I'm trying to show both Months and Posts from the beginning of time of the database.
Use a LEFT JOIN to include rows with no match:
SELECT MONTHNAME(post_time) AS month,
COALESCE(COUNT(distinct t.knote_id), 0) AS count
FROM post AS p
LEFT JOIN post_tag_map AS t
ON p.post_id = t.knote_id AND t.post_id IN (23,24,49,54)
WHERE p.post_time >= (CURDATE() - INTERVAL 1 YEAR)
GROUP BY month
Note that you have to put the t conditions in the ON clause, not WHERE, when using LEFT JOIN; otherwise, they'd fail on the non-matching rows. And you have to count the column from t, so it will skip the null value for the non-matching row.
DEMO
Try using the ISNULL(amount,0) function:
SELECT MONTHNAME(post_time) AS month,
ISNULL(Count(distinct p.post_id), 0) AS count
FROM post.p
INNER JOIN post_tag_map t ON ( p.post_id = t.knote_id )
WHERE t.post_id IN (23,24,49,54)
/*these numbers are actually a variable, this is just an example*/
AND p.post_time >= (CURDATE() - INTERVAL 1 YEAR)

Check available rooms given parameters are room type,start date, and end date

I have this table
**Rooms**
idRoom
name
**Room_details**
idRoomDetails
idRoom
idRoomType
**Bookings**
idBooking
idRoomDetails
startDate
endDate
Words that have * * are table names
The variables that I have are idRoomType , startDate, endDate.
How can I output all the rooms that are available and the given parameters are room type, startDate and endDate?
I honestly do not now how to start that's why I can't show you what I've done so far.
Your help will be greatly appreciated! Thanks! :)
If the date selection is your problem than I can give you some useful insights. You should select all rooms with following conditions in your query structure;
Booking.startDate <= "End date of the availability period you're checking"
Booking.endDate >= "Start date of the availability period you're checking"
To make it more clear, your query could look like:
SELECT * FROM Rooms
INNER JOIN Room_details ON Rooms.idRoom = Room_details.idRoom
LEFT JOIN Bookings ON Room_details.idRoomDetails = Bookings.idRoomDetails
WHERE Bookings.idBooking IS NULL
OR (Bookings.startDate <= 'availabilityEndDate'
AND Bookings.endDate >= 'availabilityStartDate')
Where 'availabilityEndDate' and 'availabilityStartDate' need to be replaced by actual dates of course.
can you try this query:
select * from Rooms r
inner join Room_details rd on
r.idRoom = rd.idRoom
left join Bookings b on
rd.idRoomDetails = b.idRoomDetails
where b.idBooking is null
and b.startDate > CURDATE()
and b.startDate > CURDATE() should check only for those rooms that have a booking in the future. You might want to try the query without this line first and see if it works. If it does work then you can always add a date checking part to the query.

sorting groups within a query

I am using the below query to paginate posts on my site:
select * from songs t1 join (
select to_days(date) day from songs
group by day
order by day desc
limit $start_row, $items_per_page
) t2
on to_days(t1.date) = t2.day
Depending on my $start_row and $items_per_page this will return all the posts for say, the last 7 days. Regardless of if there was more than 1 post per day or a day is empty and skipped.
For example:
Above the query has correctly returned all the posts from the latest 7 days. Today. Yesterday. The day before that and so on...
However if you look at the table id 12## values on the far left, and time stamp day values 73#### on the far right. You will see they are grouped backwards.
How do I switch this query around so that it returns the same results in the same grouping but in a reverse order?
For example:
Oh My! - Run This Town(TMS remix)
Lost Mapaches-Back To Basics (La Royale Remix)
Dimitri from Paris & DJ Rocca-I Need A Reason For LIving (Radio Mix)
Chromeo - Hot Mess (23 Dubstep Remix)
and so on... I tried removing the desc value but that just returns the grouping from the oldest entries in the table.
You need to add an ORDER BY to the outer select as well, not just the inner one being JOINed to.
SELECT *
FROM songs t1
JOIN (
SELECT to_days(date) day FROM songs
GROUP BY day
ORDER BY day DESC
LIMIT $start_row, $items_per_page
) t2 ON to_days(t1.date) = t2.day
ORDER BY day DESC
(That last line is the bit you need to add.)
I would order your data on the outside of the subquery (note the last line), please adjust last line for asc / desc or if you want to order by.
select * from songs t1 join (
select to_days(date) day from songs
group by day
order by day desc
limit $start_row, $items_per_page
) t2
on to_days(t1.date) = t2.day
order by id desc

Categories