0

I'm trying to write a query which does the below:

For every guest who has the word “Edinburgh” in their address show the total number of nights booked. Be sure to include 0 for those guests who have never had a booking. Show last name, first name, address and number of nights. Order by last name then first name.

I am having problems with making the join work properly, ER Diagram Snippet:

ER Diagram snippet

Here is my current (broken) solution:

SELECT last_name, first_name, address, nights
FROM booking
RIGHT JOIN guest ON (booking.booking_id = guest.id)
WHERE address LIKE '%Edinburgh%';

Here is the results from that query:

enter image description here

The query is partially complete, hoping someone can help me out and create a working version. I'm currently in the process of learning SQL so apologies if its a rather basic or dumb question!

Aidan
  • 470
  • 3
  • 7
  • 16

3 Answers3

1

Your query seems almost correct. You were joining the booking id with guets id which gave you some results because of overlapping (matching) ids, but this most likely doesn't correspond to the foreign keys. You should join on guest_id from booking to id from guest.

I'd add grouping to sum all booked nights for a particular guest (assuming that nights is an integer):

SELECT g.last_name, g.first_name, g.address, SUM(b.nights) AS nights
FROM guest AS g
LEFT JOIN booking AS b ON b.guest_id = g.id
WHERE g.address LIKE '%Edinburgh%'
GROUP BY g.last_name, g.first_name, g.address;

Are you sure that nights spent should be calculated using nights field? Why can it be null? If you'd like to show zero for null values just wrap it up with a coalesce function like that:

COALESCE(SUM(b.nights), 0)

Notes:

  • Rewriten RIGHT JOIN into LEFT JOIN, but that doesn't affect results - it's just cleaner for me
  • Using aliases eg. AS g makes the code shorter when specifying joining columns
  • Reference every column with their table alias to avoid ambiguity
Kamil Gosciminski
  • 16,547
  • 8
  • 49
  • 72
0
SELECT g.first_name,
       g.last_name,
       g.address,
       COALESCE(Sum(b.nights), 0)
FROM   booking b
       RIGHT JOIN guest g
               ON ( b.guest_id = g.id )
WHERE  address LIKE 'edinburgh%'
GROUP  BY g.last_name,
          g.first_name,
          g.address; 
Blag
  • 5,818
  • 2
  • 22
  • 45
-1

This post answers your questions about how to make the query.

MySQL SUM with same ID

You can simply use COALESCE as referenced here to avoid the NULL Values

How do I get SUM function in MySQL to return '0' if no values are found?

Community
  • 1
  • 1
Jeff
  • 143
  • 8
  • Also since you could have possibility of records with the same names I would highly recommend using the unique record ID in your process – Jeff Nov 06 '16 at 21:49