corsasport.co.uk
 

Corsa Sport » Message Board » Off Day » Geek Day » MYSQL query help


New Topic

New Poll
  Subscribe | Add to Favourites

You are not logged in and may not post or reply to messages. Please log in or create a new account or mail us about fixing an existing one - register@corsasport.co.uk

There are also many more features available when you are logged in such as private messages, buddy list, location services, post search and more.


Author MYSQL query help
pow
Premium Member

Avatar

Registered: 11th Sep 06
Location: Hazlemere, Buckinghamshire
User status: Offline
2nd Jun 14 at 10:40   View Garage View User's Profile U2U Member Reply With Quote

I'm a total beginner with this but I'm getting somewhere. I have adapted a room booking system for use at my school but now want to use a page to show what is on in which room.

I'm using the query:

SELECT name, displayname, notes FROM bookings INNER JOIN users ON (bookings.user_id = users.user_id) INNER JOIN periods ON (bookings.period_id = periods.period_id) WHERE (room_id="3" AND (date=CURDATE() or day_num=DAYOFWEEK(CURDATE()) -1)) ORDER BY bookings.period_id asc;

and it's returning 99% what I want:

+---------------+-------------------+--------+
| name | displayname | notes |
+---------------+-------------------+--------+
| 9:00 - 9:30 | Timetabled Lesson | Year 6 |
| 9:30 - 10:00 | Timetabled Lesson | Year 6 |
| 13:00 - 13:30 | Timetabled Lesson | Year 4 |
| 13:30 - 14:00 | Timetabled Lesson | Year 4 |
| 14:00 - 14:30 | Timetabled Lesson | Year 4 |
| 14:30 - 15:00 | Timetabled Lesson | Year 4 |
| 15:00 - 15:30 | Timetabled Lesson | Year 4 |
+---------------+-------------------+--------+
7 rows in set (0.00 sec)

but what I want is the NULL values for the name (which is the name of the period, each half an hour slot so it looks like this:

+---------------+-------------------+--------+
| name | displayname | notes |
+---------------+-------------------+--------+
| 9:00 - 9:30 | Timetabled Lesson | Year 6 |
| 9:30 - 10:00 | Timetabled Lesson | Year 6 |
| 10:00 - 10:30 | NULL | NULL |
| 10:30 - 11:00 | NULL | NULL |
| 11:00 - 11:30 | NULL | NULL |
| 11:30 - 12:00 | NULL | NULL |
| 12:00 - 12:30 | NULL | NULL |
| 12:30 - 13:00 | NULL | NULL |
| 13:00 - 13:30 | Timetabled Lesson | Year 4 |
| 13:30 - 14:00 | Timetabled Lesson | Year 4 |
| 14:00 - 14:30 | Timetabled Lesson | Year 4 |
| 14:30 - 15:00 | Timetabled Lesson | Year 4 |
| 15:00 - 15:30 | Timetabled Lesson | Year 4 |
+---------------+-------------------+--------+

How do I do this?

[Edited on 02-06-2014 by pow]

[Edited on 02-06-2014 by pow]
gooner_47
Member

Registered: 20th Jul 04
Location: Bexhill/Croydon
User status: Offline
2nd Jun 14 at 11:02   View User's Profile U2U Member Reply With Quote

I struggle to work these things out without looking at data and table structure etc, but try a left join or right join from bookings to periods instead of an inner join, i.e.

LEFT JOIN periods ON (bookings.period_id = periods.period_id)
pow
Premium Member

Avatar

Registered: 11th Sep 06
Location: Hazlemere, Buckinghamshire
User status: Offline
2nd Jun 14 at 11:07   View Garage View User's Profile U2U Member Reply With Quote

Yeah I was hoping that would help but it doesn't

Basically, the bookings table has a period_id in it, which relates to a period displayname, so if the room isn't booked there isn't any data
pow
Premium Member

Avatar

Registered: 11th Sep 06
Location: Hazlemere, Buckinghamshire
User status: Offline
2nd Jun 14 at 11:10   View Garage View User's Profile U2U Member Reply With Quote

I've even tried reordering the JOINs and changing the order of the two JOINs
pow
Premium Member

Avatar

Registered: 11th Sep 06
Location: Hazlemere, Buckinghamshire
User status: Offline
2nd Jun 14 at 11:14   View Garage View User's Profile U2U Member Reply With Quote

I've rewritten that query like 50 times in different ways and my output looks EXACTLY the same

[Edited on 02-06-2014 by pow]
Baskey
Member

Registered: 31st May 06
User status: Offline
2nd Jun 14 at 11:41   View User's Profile U2U Member Reply With Quote

Select a top 10 * from each of the tables and post them up so i can see what the tables look like.


If we can see your tables we could fix it very quickly !
Dom
Member

Registered: 13th Sep 03
User status: Offline
2nd Jun 14 at 11:42   View User's Profile U2U Member Reply With Quote

Struggling without the data in front of me but joining the users and booking tables on to the period table, essentially filling in the 'blanks', should work.
pow
Premium Member

Avatar

Registered: 11th Sep 06
Location: Hazlemere, Buckinghamshire
User status: Offline
2nd Jun 14 at 11:48   View Garage View User's Profile U2U Member Reply With Quote

Okay here is the periods table:

+-----------+-----------+------------+----------+---------------+------+----------+
| period_id | school_id | time_start | time_end | name | days | bookable |
+-----------+-----------+------------+----------+---------------+------+----------+
| 1 | 1 | 07:30:00 | 08:30:00 | Before School | 62 |1 |
| 2 | 1 | 08:30:00 | 09:00:00 | 8:30 - 9:00 | 62 |1 |
| 3 | 1 | 09:00:00 | 09:30:00 | 9:00 - 9:30 | 62 |1 |
| 4 | 1 | 09:30:00 | 10:00:00 | 9:30 - 10:00 | 62 |1 |
| 5 | 1 | 10:00:00 | 10:30:00 | 10:00 - 10:30 | 62 |1 |
| 6 | 1 | 10:30:00 | 11:00:00 | 10:30 - 11:00 | 62 |1 |
| 7 | 1 | 11:00:00 | 11:30:00 | 11:00 - 11:30 | 62 |1 |
| 8 | 1 | 11:30:00 | 12:00:00 | 11:30 - 12:00 | 62 |1 |
| 9 | 1 | 12:00:00 | 12:30:00 | 12:00 - 12:30 | 62 |1 |
| 10 | 1 | 12:30:00 | 13:00:00 | 12:30 - 13:00 | 62 |1 |
+-----------+-----------+------------+----------+---------------+------+----------+

and the bookings

+------------+-----------+-----------+---------+---------+---------+---------+------+--------+-----------+
| booking_id | school_id | period_id | week_id | day_num | room_id | user_id | date | notes | cancelled |
+------------+-----------+-----------+---------+---------+---------+---------+------+--------+-----------+
| 24 | 1 | 3 | 1 | 1 | 3 | 1 | NULL | Year 6 | 0 |
| 25 | 1 | 4 | 1 | 1 | 3 | 1 | NULL | Year 6 | 0 |
| 31 | 1 | 11 | 1 | 1 | 3 | 1 | NULL | Year 4 | 0 |
| 32 | 1 | 12 | 1 | 1 | 3 | 1 | NULL | Year 4 | 0 |
| 33 | 1 | 13 | 1 | 1 | 3 | 1 | NULL | Year 4 | 0 |
| 34 | 1 | 15 | 1 | 1 | 3 | 1 | NULL | Year 4 | 0 |
| 35 | 1 | 10 | 1 | 2 | 3 | 1 | NULL | Year 2 | 0 |
| 36 | 1 | 11 | 1 | 2 | 3 | 1 | NULL | Year 2 | 0 |
| 37 | 1 | 12 | 1 | 2 | 3 | 1 | NULL | Year 2 | 0 |
| 38 | 1 | 13 | 1 | 2 | 3 | 1 | NULL | Year 2 | 0 |
+------------+-----------+-----------+---------+---------+---------+---------+------+--------+-----------+

The users just maps the user_id to a displayname (which is their fullname)

[Edited on 02-06-2014 by pow]
Baskey
Member

Registered: 31st May 06
User status: Offline
2nd Jun 14 at 11:58   View User's Profile U2U Member Reply With Quote

Ok start with the periods table as the first table in your statement then left outer join the other tables
Baskey
Member

Registered: 31st May 06
User status: Offline
2nd Jun 14 at 12:00   View User's Profile U2U Member Reply With Quote

So

periods

Left outer Join to bookings

Left outer joing to users

In that order

[Edited on 02-06-2014 by Baskey]
pow
Premium Member

Avatar

Registered: 11th Sep 06
Location: Hazlemere, Buckinghamshire
User status: Offline
2nd Jun 14 at 12:03   View Garage View User's Profile U2U Member Reply With Quote

SELECT name, displayname, notes FROM periods LEFT OUTER JOIN bookings ON (periods.period_id = bookings.period_id) LEFT OUTER JOIN users ON (bookings.user_id = users.user_id) WHERE (room_id="3" AND (date=CURDATE() or day_num=DAYOFWEEK(CURDATE()) -1)) ORDER BY bookings.period_id asc;

produces:

+---------------+-------------------+--------+
| name | displayname | notes |
+---------------+-------------------+--------+
| 9:00 - 9:30 | Timetabled Lesson | Year 6 |
| 9:30 - 10:00 | Timetabled Lesson | Year 6 |
| 13:00 - 13:30 | Timetabled Lesson | Year 4 |
| 13:30 - 14:00 | Timetabled Lesson | Year 4 |
| 14:00 - 14:30 | Timetabled Lesson | Year 4 |
| 14:30 - 15:00 | Timetabled Lesson | Year 4 |
| 15:00 - 15:30 | Timetabled Lesson | Year 4 |
+---------------+-------------------+--------+

:(
Dom
Member

Registered: 13th Sep 03
User status: Offline
2nd Jun 14 at 12:04   View User's Profile U2U Member Reply With Quote

quote:
Originally posted by Baskey
Ok start with the periods table as the first table in your statement then left outer join the other tables


As already mentioned; although it does restrict you to a single day
pow
Premium Member

Avatar

Registered: 11th Sep 06
Location: Hazlemere, Buckinghamshire
User status: Offline
2nd Jun 14 at 12:04   View Garage View User's Profile U2U Member Reply With Quote

Chnaged the ON about as well:

SELECT name, displayname, notes FROM periods LEFT OUTER JOIN bookings ON (bookings.period_id = periods.period_id) LEFT OUTER JOIN users ON (bookings.user_id = users.user_id) WHERE (room_id="3" AND (date=CURDATE() or day_num=DAYOFWEEK(CURDATE()) -1)) ORDER BY bookings.period_id asc;

Same thing
Dom
Member

Registered: 13th Sep 03
User status: Offline
2nd Jun 14 at 14:35   View User's Profile U2U Member Reply With Quote

Need to LEFT JOIN the bookings and format your queries properly -
code:
SELECT `periods`.`name`, `bookings`.`notes` FROM `periods` LEFT JOIN `bookings` ON `periods`.`period_id` = `bookings`.`period_id` WHERE 1


Results in -

+---------------+--------+
| name | notes |
+---------------+--------+
| Before School | NULL |
| 8:30 - 90 | NULL |
| 90 - 9:30 | Year 6 |
| 9:30 - 100 | Year 6 |
| 100 - 10:30 | NULL |
| 10:30 - 110 | NULL |
| 110 - 11:30 | NULL |
| 11:30 - 120 | NULL |
| 120 - 12:30 | NULL |
| 12:30 - 130 | NULL |
| 130 - 13:30 | Year 6 |
| 13:30 - 140 | Year 6 |
| 140 - 14:30 | Year 6 |
| 14:30 - 150 | NULL |
| 150 - 13:30 | Year 6 |
+---------------+--------+


Edit - As said though, this will only work for a single day; if you needed to pull bookings out across multiple days then i'd look at doing the logic in your scripting rather than within the query.

Edit 2 - My bad; the above fails as soon as you applying conditions

[Edited on 02-06-2014 by Dom]
pow
Premium Member

Avatar

Registered: 11th Sep 06
Location: Hazlemere, Buckinghamshire
User status: Offline
2nd Jun 14 at 14:45   View Garage View User's Profile U2U Member Reply With Quote

No I only need a single day as it's to go on a screen outside the room to show what's on today so that's fine

And go easy on me, this is my first ever dive into both PHP and MYSQL

[Edited on 02-06-2014 by pow]
pow
Premium Member

Avatar

Registered: 11th Sep 06
Location: Hazlemere, Buckinghamshire
User status: Offline
2nd Jun 14 at 14:54   View Garage View User's Profile U2U Member Reply With Quote

I do appreciate the help though
Dom
Member

Registered: 13th Sep 03
User status: Offline
2nd Jun 14 at 15:04   View User's Profile U2U Member Reply With Quote

A subquery on the FROM clause might work; give me a minute....


It's not pretty and i suspect it could be a lot better but try something like this (changed formatting just to make it easier to read) -
code:
SELECT `periods`.`name`, `xb`.`notes`
FROM
(
SELECT `bookings`.`period_id`, `bookings`.`notes`, `bookings`.`user_id`
FROM `bookings`
WHERE `bookings`.`room_id` = '3'
) AS xb
RIGHT JOIN `periods`
ON `periods`.`period_id` = `xb`.`period_id`
WHERE 1


Essentially the subquery formats the booking data outside of the 'main' query, prevents the 'main' query conditions affecting the booking data. Obviously tack on the users table as another join and similarly add date/day/time conditions to the subquery.

Edit - Added users etc -
code:
SELECT `periods`.`name` AS `period_name`, `xb`.`notes`, `users`.`name` AS `user_name`
FROM
(
SELECT `bookings`.`period_id`, `bookings`.`notes`, `bookings`.`user_id`
FROM `bookings`
WHERE `bookings`.`date` = '2014-01-01' AND `bookings`.`room_id` = '3'
) AS xb
RIGHT JOIN `periods`
ON `periods`.`period_id` = `xb`.`period_id`
LEFT JOIN `users`
ON `users`.`user_id` = `xb`.`user_id`
WHERE 1


Which should give you something like -
+----------------+--------+-------------+
| period_name | notes | user_name |
+----------------+--------+-------------+
| Before School | NULL | NULL |
| 8:30 - 9:00 | NULL | NULL |
| 9:00 - 9:30 | Year 6 | Bob |
| 9:30 - 10:00 | Year 1 | Dave |
| 10:00 - 10:30 | NULL | NULL |
| 10:30 - 11:00 | NULL | NULL |
| 11:00 - 11:30 | NULL | NULL |
| 11:30 - 12:00 | NULL | NULL |
| 12:00 - 12:30 | NULL | NULL |
| 12:30 - 13:00 | NULL | NULL |
| 13:00 - 13:30 | Year 6 | Bob |
| 13:30 - 14:00 | Year 4 | Hannah |
| 14:00 - 14:30 | Year 6 | Bob |
| 14:30 - 15:00 | NULL | NULL |
| 15:00 - 13:30 | NULL | NULL |
+---------------+--------+--------------+

[Edited on 02-06-2014 by Dom]

[Edited on 02-06-2014 by Dom]
pow
Premium Member

Avatar

Registered: 11th Sep 06
Location: Hazlemere, Buckinghamshire
User status: Offline
2nd Jun 14 at 17:35   View Garage View User's Profile U2U Member Reply With Quote

Dom you are nothing short of a legend, I'm just messing around with it to get it as I want it!
pow
Premium Member

Avatar

Registered: 11th Sep 06
Location: Hazlemere, Buckinghamshire
User status: Offline
2nd Jun 14 at 17:43   View Garage View User's Profile U2U Member Reply With Quote

Just tweaked it:

code:

SELECT `periods`.`name` AS `period_name`, `xb`.`notes`, `users`.`displayname` AS `displayname`

FROM

(

SELECT `bookings`.`period_id`, `bookings`.`notes`, `bookings`.`user_id`

FROM `bookings`

WHERE `bookings`.`room_id` = '3'

AND ((`bookings`.`date` = CURDATE()) OR (`bookings`.`day_num` = DAYOFWEEK(CURDATE()) -1))

) AS xb

RIGHT JOIN `periods`

ON `periods`.`period_id` = `xb`.`period_id`

LEFT JOIN `users`

ON `users`.`user_id` = `xb`.`user_id`

WHERE 1

Dom
Member

Registered: 13th Sep 03
User status: Offline
2nd Jun 14 at 17:56   View User's Profile U2U Member Reply With Quote

quote:
Originally posted by pow
Dom you are nothing short of a legend, I'm just messing around with it to get it as I want it!


There's probably a better/more efficient query to do it but no worries, glad it worked
pow
Premium Member

Avatar

Registered: 11th Sep 06
Location: Hazlemere, Buckinghamshire
User status: Offline
2nd Jun 14 at 18:17   View Garage View User's Profile U2U Member Reply With Quote

Meh, the page loads in less than a second so that's fine for me!

 
New Topic

New Poll

  Related Threads Author Forum Replies Views Last Post
mysql function help :D waynep Geek Day 2 1359
20th Jul 03 at 20:59
by waynep
 
(my)SQL dudes Dom Geek Day 9 640
3rd May 07 at 23:50
by Dom
 
php and mysql help please bigD21 Geek Day 4 429
30th Aug 08 at 16:46
by bigD21
 
Php help? (mysql_num_rows) Whittie Geek Day 17 1518
15th Jan 10 at 14:38
by Dom
 
MySQL Folk Dom Geek Day 20 852
6th Dec 11 at 01:23
by Ian
 

Corsa Sport » Message Board » Off Day » Geek Day » MYSQL query help 29 database queries in 0.0160511 seconds