Can't solve this sql statement to archive my real goal - mysql

SELECT hotel.hotel_id, hotel.hotel_name, hotel.hotel_address, hotel.hotel_pic,
room_accommodation.room_full_price
FROM hotel
INNER JOIN room_accommodation ON (room_accommodation.hotel_id = hotel.hotel_id )
INNER JOIN (
SELECT MIN( room_full_price ) AS minPrice
FROM room_accommodation INNER JOIN hotel ON (
hotel.hotel_id =room_accommodation.hotel_id )
WHERE hotel.hotel_address LIKE '%bangkok%'
)room_accommodation ON room_accommodation.room_full_price = room_accommodation.minPrice
This SQL can query each hotel that are in bangkok with a lowest rate of each hotel
But the problem is now I want to query all lowest rate of each hotel but when I cut
the condition where out the result just gave me only one lowest price of all hotel
what wrong and what should I do to archive this
Please Advice
Thank in advance.

This can be greatly simplified - there's no need for a subquery based on the results you need:
SELECT hotel.hotel_id,
hotel.hotel_name,
hotel.hotel_address,
hotel.hotel_pic,
MIN(room_accommodation.room_full_price) as room_full_price
FROM hotel
INNER JOIN room_accommodation
ON room_accommodation.hotel_id = hotel.hotel_id
AND hotel.hotel_address LIKE '%bangkok%'
GROUP BY hotel.hotel_id
Note that for other DBMS's you would need to specify each non-aggregate field in the GROUP BY clause. MySQL lets you get away without that - for better or worse.

i guess u are giving wrong alias to to ur inner query [room_accommodation]
ur query shows that u also have a table with name room_accommodation
SELECT hotel.hotel_id, hotel.hotel_name, hotel.hotel_address, hotel.hotel_pic,
room_accommodation.room_full_price
FROM hotel
INNER JOIN ***room_accommodation*** ON (room_accommodation.hotel_id = hotel.hotel_id )
INNER JOIN (
SELECT MIN( room_full_price ) AS minPrice
FROM room_accommodation INNER JOIN hotel ON (
hotel.hotel_id =room_accommodation.hotel_id )
WHERE hotel.hotel_address LIKE '%bangkok%'
)***room_accommodation*** ON room_accommodation.room_full_price = room_accommodation.minPrice

Related

Write a query to find the full names of customers who have rented sci-fi movies more than 5 times. Arrange these names in the alphabetical order

Hello below is my Code
DB: https://dev.mysql.com/doc/sakila/en/sakila-structure.html
select concat(first_name,' ',last_name) from
customer where customer_id in (
select customer_id from (
select customer_id, count(rental_id) as num
from
category
inner join film_category using(category_id)
inner join film using(film_id)
inner join inventory using(film_id)
inner join rental using (inventory_id)
where name='Sci-Fi'
group by customer_id, rental_id)
where num > 5)T)
when i am executing i am getting the below error
ERROR 1248 (42000) at line 2: Every derived table must have its own alias
Expected Outcome is "full names of customers who have rented sci-fi movies more than 5 times. Arrange these names in the alphabetical order"
Could you please let me know what is the mistake i am doing?
Welcome to SO!
First, it seems like you have 3 opening ( parens and 4 closing ) parens. You should delete the last parenthesis so you have balanced parens.
After that, you want to apply the alias to the deepest level query. (Similar question: What is the error “Every derived table must have its own alias” in MySQL?) You have...
where name='Sci-Fi'
group by customer_id, rental_id)
where num > 5)T)
You probably want...
where name='Sci-Fi'
group by customer_id, rental_id) AS T
where num > 5)
(Don't forget, there is no need for that extra closing paren, so you can see I removed it. It might be part of a bigger query you have, but it doesn't help the standalone code in the question.)
This will stop the immediate error that you're seeing. At least, now on my database, the error I see is: ERROR 1146 (42S02): Table 'db.customer' doesn't exist.
select concat(first_name, ' ', last_name) as Customer_name
from category
inner join film_category
using (category_id)
inner join film
using (film_id)
inner join inventory
using (film_id)
inner join rental
using (inventory_id)
inner join customer
using (customer_id)
where name = 'Sci-Fi'
group by Customer_name
having count(rental_id) > 3
order by Customer_name;
select concat(first_name,' ',last_name) as customer_name from customer
inner join rental
using(customer_id)
inner join inventory
using(inventory_id)
inner join film
using(film_id)
inner join film_category
using(film_id)
inner join category
using(category_id)
where name in ('sci-fi')
group by customer_name
having count(rental_id) > 2
order by customer_name

Subquery returns multiple rows in HAVING clause

I want to get the customer who mostly borrowed films of category 3 in 2016, July
SELECT c_firstName, c_lastName, rental.c_ID
FROM customer, rental
GROUP BY rental.c_ID HAVING rental.c_ID=MAX((SELECT COUNT(rental.c_ID)
FROM customer, copies, rentalprocess, rental, film
WHERE customer.c_ID=rental.c_ID AND rentalprocess.r_ID=rental.r_ID AND
rentalprocess.s_ID=copies.s_ID AND film.f_ID=copies.f_ID AND
f_category=3 AND r_date LIKE "2016-07%" GROUP BY rental.c_ID))
But ir doesn't work because it said that the subquery returns more than one row
What can I do?
Max() is an aggregate function that needs to be in a select statement
SELECT
c_firstName
, c_lastName
, rental.c_ID
FROM customer, rental
GROUP BY rental.c_ID
HAVING rental.c_ID=
(
select
MAX(i.iID)
from
(
SELECT
COUNT(rental.c_ID) iID
FROM customer, copies, rentalprocess, rental, film
WHERE
customer.c_ID=rental.c_ID AND
rentalprocess.r_ID=rental.r_ID AND
rentalprocess.s_ID=copies.s_ID AND
film.f_ID=copies.f_ID AND
f_category=3
AND r_date LIKE "2016-07%"
GROUP BY rental.c_ID
) i
)
In this case the sub-select returns multiple rows but then you take the max value of that query
Comment from Mr Linoff is correct, you should use explicity joins:
SELECT
c_firstName
, c_lastName
, rental.c_ID
FROM customer, rental
GROUP BY rental.c_ID
HAVING rental.c_ID=
(
select
MAX(i.iID)
from
(
SELECT
COUNT(rental.c_ID) iID
FROM
customer
inner join rental
on customer.c_ID=rental.c_ID
inner join rentalprocess
on rentalprocess.r_ID=rental.r_ID
inner join copies
on rentalprocess.s_ID=copies.s_ID
inner join film on film.f_ID=copies.f_ID
WHERE
f_category=3
AND r_date LIKE "2016-07%"
GROUP BY rental.c_ID
) i
)
your code should look something like this, join the tables properly in the code.
I dont know wich columns and table would suit best for the solution becuse I dont got your full schema. but this should give faster query. Put more columns in the select if you wish.
select c_firstName | ' ' | c_lastName, count(rental.c_ID) as rentalCustomer
from customer
inner join rental
on join " connect the both tables"
innner join rentalprocess
on "connect rental with rentalprocess"
inner join copies
on " connect rentalprocess with copies"
inner join film
on "connect copies with film"
WHERE customer.c_ID=rental.c_ID AND
rentalprocess.r_ID=rental.r_ID AND
rentalprocess.s_ID=copies.s_ID AND
film.f_ID=copies.f_ID AND
f_category=3 AND r_date LIKE "2016-07%"
group by c_firstName, c_lastName, rental.c_ID
order by rental.c_ID desc;

MySQL: How to Join two table and Group By based latest records for each record

hi, I have a problem with MySQL.
I want to group by records based on latest records
I designed my tables and desire result in above image
please help me. thanks
You can get latest (inserted_date) for every PID then use that as separate table.
Eg:
SELECT P.PID, S.SID, P.PRODUCTNAME, S.PRICE, S.COUNT, S.INSERTED_DT FROM
PRODUCT P
INNER JOIN
(
SELECT PID, MAX(INSERTED_DATE) AS LATEST_DT FROM STOCK
) P1 ON P.PID = P1.PID
INNER JOIN STOCK S ON S.PID = P.PID AND S.INSERTED_DATE = P1.LATEST_DT

MySQL subquery on multiple tables

I am trying to retrieve names and address of all guests with bookings for a hotel in London, alphabetically ordered by name in MySQL using subqueries and getting this Error:
Error Code: 1242. Subquery returns more than 1 row
Here's the query that I run:
select * from guest
where guest_no =
(
select guest_no
from booking
where hotel_no = (select hotel_no
from hotel
where city = 'London')
);
and here's the schema for hotel, booking and guest:
hotel (hotel_no, hotel_name, city)
booking (hotel_no, guest_no, date_from, date_to, room_no)
guest (guest_no, g_name, g_address)
additionally, here's the schema for room:
room (room_no, hotel_no, type, price)
Please help me with the above mentioned error and possible solutions.
Thanks and regards.
why not use join as
select
g.guest_no,
g.g_name,
g.g_address
from guest g
inner join booking b on b.guest_no = g.guest_no
inner join hotel h on h.hotel_no = b.hotel_no
where h.city = 'London'
When you use '=', it means that the result of your subquery is exactly 1 row. If you expect multiple results, you need to use the IN keyword, like so:
select * from guest where guest_no IN (select guest_no from booking where hotel_no IN (select hotel_no from hotel where city = 'London'));
EDIT: As #flaschenpost mentions, the performance could be degraded in case there is no proper indexing on the columns involved in the subqueries. You would probably do well to use JOIN rather than such nested subqueries.
Change you query to
select * from guest
where guest_no IN
(select guest_no from booking where hotel_no
IN (select hotel_no from hotel where city = 'London'));
you need joins !
try this !
select a.g_name,a.g_address from guest a inner join booking b on a.guest_no=b.guest_number inner join hotel h on b.hotel_no=h.hotel_no inner join rooms r on b.room_no=h.room_no
where h.city='London'

MySql Query Optimisation, replacing not in subquery with join

I have a query that I feel is very bulky and can do with optimisation. First thing would obviously be replacing not in subquery with join but it affects the sub-sub query that I have. I'd appreciate suggestions/workaround on it.
This is the query
SELECT *
FROM lastweeksales
WHERE productID = 1234
AND retailer NOT
IN (
SELECT retailer
FROM sales
WHERE productID
IN (
SELECT productID
FROM products
WHERE publisher = 123
)
AND DATE = date(now())
)
Basically, I want to get rows from lastweek's sales on a product where retailers are not present that did sales today but sales should only be on products by a certain publisher.
:S:S:S
You can group together 2 inner subqueries easily via INNER JOIN. For the outer one you should use LEFT OUTER join and then filter on retailer IS NULL, like this:
SELECT lws.*
FROM lastweeksales lws
LEFT JOIN (SELECT s.retailer
FROM sales s
JOIN products p USING (productID)
WHERE p.publisher = 123
AND s.date = date(now())) AS r
ON lws.retailer = r.retailer
WHERE r.retailer IS NULL;