I’ve written a query that is the equivalent of asking someone to go find a sock but to also return anything else they found along with it.
I have bookings, each of which have a one-to-many relationship with one to [n] data objects. While I’m asking the database to find one of those data objects, I actually need it to retrieve any other data objects it might find. Alas, it’s not working that way and it’s only returning what it’s finding.
I’ve emboldened the part of the query which is the source of my angst.
I’m sure this is a very common problem, but I can’t articulate the problem to even search for a solution!
As always, any advice would be warmly received.
SELECT
bookings.booking_id,
DATE_FORMAT(bookings.creation_date, '%a %D %b %y') AS creation_date,
DATE_FORMAT(bookings.modification_date, '%a %D %b %y') AS modification_date,
bookings.client_id,
bookings_attendees.name,
DATE_FORMAT(bookings_attendees.stay_date, '%a %D %b %y') AS stay_date,
bookings_attendees.stay_nights,
venues.venue_id AS venue_id,
venues.name AS venue,
venues.town_city,
DATE_FORMAT((
SELECT
MAX(bookings_history.modification_date) AS booking_history
FROM bookings_history
WHERE
(bookings_history.booking_id = bookings.booking_id)
), '%a %D %b %y, %H:%i') AS booking_history,
COALESCE(GROUP_CONCAT(DISTINCT bookings_clients_options_data.value SEPARATOR 0x1D), 'NULL') AS clients_options
FROM
bookings_attendees
INNER JOIN
bookings
ON
(bookings.booking_id = bookings_attendees.booking_id)
AND
(bookings.client_id = '3')
AND
(bookings.status = 'confirmed')
AND
(bookings.mode = 'public')
INNER JOIN
bookings_clients
ON
(bookings.booking_id = bookings_clients.booking_id)
INNER JOIN
clients
ON
(clients.client_id = bookings_clients.client_id)
AND
(clients.client_id = '1')
INNER JOIN
venues
ON
(venues.venue_id = bookings.venue_id)
[B]INNER JOIN
bookings_clients_options
ON
(bookings_clients_options.client_id = '3')
INNER JOIN
bookings_clients_options_data
ON
(bookings_clients_options.bookings_client_option_id = bookings_clients_options_data.bookings_client_option_id)
AND
(bookings_clients_options_data.booking_attendee_id = bookings_attendees.booking_attendee_id)
WHERE
(bookings_clients_options_data.bookings_client_option_id = '4')[/B]
GROUP BY bookings.booking_id
ORDER BY bookings_attendees.stay_date
ASC
bookings and bookings_attendees both contain the actual booking data (split because it supports more than one booking per person made in one session);
clients isn’t necessarily required here, but is necessary for when other types of user are using the system, and is required to determine which client they belong to;
venues is the venue to which the booking relates;
bookings_clients_options contains the custom fields which the client can use to capture data beyond the mandatory fields required for the booking (name, email, venue, stay date, number of nights et cetera);
bookings_clients_options_data is for the actual data objects themselves.
As for your question … think about my opening sentence for a minute and then tell me if you realised I was being sarcastic.
if you were being sarcastic then i am sorry because i don’t see from your query why if it’s not finding what it wasn’t asked to find that this is a problem
No, it is finding the “sock”, but it’s not returning the “sofa” it was behind and the “carpet” they both sat on. It’s an example I used to the client to explain how weird the query needs to be.
Okay, so booking 54,321 has three data objects; 123, 124, and 125. I run the query to see if data object 125 is the sock, and if so, return 123 “sofa” and 124 “carpet”, too. Or, more specifically, any data objects it can find. Presently, it’s only returning what it finds, which is the sock.
Because there’s a parent-child relationship to the clients. In this instance, the company the system belongs to is the client and their customer “client” is a child of that.
I wouldn’t be concerned with the client side of things; it’s a piece of code that’s present in about 70% of the queries throughout the system, and is working.
I’ll confess, it’s not the ideal structure (I intend changing this at a later date), but it was a design forced on me by circumstance at the time.