Find properties by availability in foreign table using MySQL - mysql

Below are my tables
properties bookings
========== ==========
property_id booking_id
price property_id
city checkin_date
checkout_date
I have two tables, Properties and Bookings for a rental site. I want to do a search by check in date, check out date, price and location. It will check the availability from the foreign table bookings via the property_id FK.
Basically I want it to be something like:
SELECT property_id,price,city FROM properties
WHERE
price > 200,
city = "Toronto",
LEFT JOIN (
SELECT postid, COUNT( * ) AS total
FROM bookings
WHERE checkin_date *** SOMEHTING HERE ****
I am sure the above is incorrect already. Whether if I am to use left join or inner join.

SELECT DISTINCT p.property_id, p.price, p.city
FROM properties AS p
LEFT JOIN bookins AS b ON p.property_id = b.property_id
WHERE p.price > 200
AND p.city = 'Toronto'
AND (b.checkin_date >= '?' OR b.checkout_date <= '?')
replace ? with your search date

Related

Nested Query - Two Level Filtering

Schema
Researcher(ID (PK), )
Activity (PID (publication_FK, PK) , RID (researcher_FK , PK))
Publication (ID (PK) , Year)
PID , RID in Activity form its composite PK and each correspond to the FK of the Publication and Researcher tables, respectively
Query
For each researcher, who was has at least 2 publications, retrieve all their publications since the year 2000
Attempt
SELECT PID, RID
FROM Activity
WHERE RID IN (SELECT RID
FROM Activity
GROUP BY RID
HAVING COUNT(RID) >= 2)
How do I filter this interim result by Publication Year?
You need to join to publications. Using your approach:
SELECT a.PID, a.RID
FROM Activity a JOIN
Publications p
ON p.ID = a.PID
WHERE p.year >= 2000 AND
a.RID IN (SELECT a2.RID
FROM Activity a2
GROUP BY a2.RID
HAVING COUNT(*) >= 2
) ;

How to make a SQL query

I'm new to SQL, so I've got some troubles with creating queries.
My task is: To select a description of a product which was selling the most in 1989 with maximum discount.Product Table. Price table. What I tried to do is
Select maximum discount by subtracting list_price - min_price
select max(list_price - min_price) from PRICE
Select description
select description from product
join price on PRODUCT.product_id = PRICE.product_id
where start_date = '1989'
The problem is that I can't make it in one query
select top 1
product.product_id,
description,
max_disc = max(list_price - min_price)
from PRICE
join product on product.product_id = PRICE.product_id
where start_date = '1989'
group by product.product_id, description
order by max_disc desc
Inner Join between the two tables using product_id, and calculate ist_price - min_price AS discount
Filter out the resultset to carry prices of 1989 only, using where YEAR(start_date) = 1989
Consider the resultset as a Derived Table, and sort it using discount value in descending order. Use Limit 1 to find the product with maximum discount given in the year 1989.
For MySQL, try the following:
SELECT dt.*
FROM (
SELECT
pt.product_id,
pt.description,
pe.list_price - pe.min_price AS discount
FROM PRODUCT AS pt
JOIN PRICE AS pe ON pt.product_id = pe.product_id
WHERE YEAR(pe.start_date) = 1989
) AS dt
ORDER BY dt.discount DESC LIMIT 1
you try like below
select * from
(
select description from product
join price
on PRODUCT.product_id = PRICE.product_id
where start_date = '1989'
) t1
cross join (select max(list_price - min_price) as p from PRICE) t

MySQL - Marking duplicates from several table fields, as well as data from another table

I have two tables - one shows user purchases, and one shows a product id with it's corresponding product type.
My client wants to make duplicate users inactive based on last name and email address, but wants to run the query by product type (based on what type of product they purchased), and only wants to include user_ids who haven't purchased paint (product ids 5 and 6). So the query will be run multiple times - once for all people who have purchased lawnmowers, and then for all people who have purchased leafblowers etc (and there will be some overlap between these two). No user_id that has purchased paint should be made inactive.
In terms of who should stay active among the duplicates, the one to stay active will be the one with the highest product id purchased (as products are released annually). If they have multiple records with the same product id, the record to stay active will be the one with most recent d_modified and t_modified.
I also want to shift the current value of 'inactive' to the 'previously_inactive' column, so that this can be easily reversed if need be.
Here is some sample table data
If the query was run by leafblower purchases, rows 5, 6, and 7 would be made inactive. This is the expected output:
If the query was run by lawnmower purchases, rows 1 and 2 would be made inactive. This would be the expected output:
If row 4 was not the most recent, it would still not be made inactive, as user_id 888 had bought paint (and we want to exclude these user_ids from being made inactive).
This is an un-optimised version of the query for 'leafblower' purchases (it is working, but will probably be too slow in the interface):
UPDATE test.user_purchases
SET inactive = 1
WHERE id IN (
SELECT z.id
FROM (SELECT * FROM test.user_purchases) z
WHERE z.product_id IN (
SELECT product_id
FROM test.products
WHERE product_type IN ("leafblower")
)
AND id NOT IN (
SELECT a.id
FROM (SELECT * FROM test.user_purchases) a
INNER JOIN (
SELECT r.surname, r.email
FROM (SELECT * FROM test.user_purchases) r
JOIN test.products s on r.product_id = s.product_id
WHERE s.product_type IN ("paint")
) b
WHERE a.surname = b.surname
AND a.email = b.email
)
AND id NOT IN (
SELECT MAX(z.id)
FROM (SELECT * FROM test.user_purchases) z
WHERE z.product_id IN (
SELECT product_id
FROM test.products
WHERE product_type IN ("leafblower")
)
AND id NOT IN (
SELECT a.id
FROM (SELECT * FROM test.user_purchases) a
INNER JOIN (
SELECT r.surname, r.email
FROM (SELECT * FROM test.user_purchases) r
JOIN test.products s on r.product_id = s.product_id
WHERE s.product_type IN ("paint")
) b
WHERE a.surname = b.surname
AND a.email = b.email
)
GROUP BY surname, email
)
)
Any suggestions on how I can streamline this query and optimise the speed of it would be much appreciated.

Mysql Query Search By Dates

I try to create a query which shows available hotels between checkin and checkout dates. Also when I make a reservation for specific rooms, I set their booking column as 1. That means, when the checkout date comes in real life, a trigger function will set that booked column as 0.
If all rooms of a hotel are booked(booked=1) and checkin-checkout dates of those rooms are specific date(checkin-checkout inputs), then don't put that hotel in the list. My query doesn't show the result that I want.
Query: Inputs: Country(state), checkin and checkout.
SELECT DISTINCT a.* FROM accommodation a INNER JOIN cb_states s ON a.state = s.id
INNER JOIN accommodation_rooms ar ON a.id = ar.accommodation
WHERE state = 1 AND a.id NOT IN
(
SELECT 1 FROM booking b
WHERE
(
(b.arrival_date BETWEEN '2017-11-16' AND '2018-03-16')
OR
(b.departure_date BETWEEN '2017-11-16' AND '2018-03-16')
)
)
When I run the query, it always shows all hotels no matter dates. If I write ... WHERE ar.booked = 0 AND state = 1 AND a.id NOT IN..., then it doesn't show accommodation id 13, but it doesn't show either when I change dates.
accommodation table:
accommodation_rooms table:
booking table:
booked_rooms table:(has foreign key with booking table)
You have multiple issues with your query:
The NOT IN list has SELECT 1. That doesn't give a great variety to the NOT IN list.
Your logic for overlaps is wrong.
I think you need to connect accommodation rooms to booked accommodation rooms.
So:
SELECT DISTINCT a.*
FROM accommodation a INNER JOIN
cb_states s
ON a.state = s.id INNER JOIN
accommodation_rooms ar
ON a.id = ar.accommodation
WHERE s.state = 1 AND
a.id NOT IN (SELECT br.accommodation_room
FROM booking b JOIN
booked_room br
ON b.?? = br.??
WHERE b.arrival_date <= '2018-03-16' AND
b.departure_date >= '2017-11-16'
);

need help with tricky mySQL query

I'm asking for an awful lot here - but maybe some SQL guru can show me how to extract the data I want and save me 10+ hours of google-time(tm)?
These are my tables, with only relevant fields displayed:
**event**
id
cust_id
....
.
**art**
id
art_name
...
.
**event_art**
event_id
art_id
...
.
**price**
cust_id
art_id
price
...
Prices in the "price" DB with user ID "0" is standard price, if an entry exists with art_id and cust_id that is customer specific price for that article.
What I have is cust_id and what I have for output now is just the customer specific prices with SQL:
SELECT * FROM price WHERE cust_id='{$custID}'
But I'd like to include prices for previously ordered articles, even if they do not have a customer specific price.
So what I need is to:
1 Get all id's from table event where cust_id = custID
2 Get all distinct article ID's on those orders from table event_art
3 Output "id" and "art_name" of article from "art" and "price" from price table using custID or 0 for standard price if no entry exists.
To me this sounds like a multi-line JOIN that's a bit outside my scope of SQL knowledge. Could somebody help me out, point me to a guide that deals with similar issues or... well, something?
Thanks in advance!
SELECT art_id, price
FROM price
WHERE cust_id = $cust_id
UNION ALL
SELECT art_id, price
FROM (
SELECT DISTINCT art_id
FROM event e
JOIN event_art ea
ON ea.event_id = e.id
WHERE e.cust_id = $cust_id
AND ea.art_id NOT IN
(
SELECT art_id
FROM price
WHERE cust_id = $cust_id
)
) e
JOIN price p
ON p.cust_id = 0
AND p.art_id = e.art_id
Make sure that (cust_id, art_id) (in this order) is a PRIMARY KEY or a UNIQUE INDEX on price.
Had to make some small changes to indicate which table was used where in the SQL, but pretty much copy&paste so not bad at all :P
SELECT price.art_id, price.price
FROM price
WHERE cust_id =114
UNION ALL
SELECT e.art_id, p.price
FROM (
SELECT DISTINCT art_id
FROM event e
JOIN event_art ea ON ea.event_id = e.id
WHERE e.cust_id =114
AND ea.art_id NOT
IN (
SELECT price.art_id
FROM price
WHERE cust_id =114
)
)e
JOIN price p ON p.cust_id =0
AND p.art_id = e.art_id
SELECT DISTINCT
a.id,
a.art_name,
COALESCE(p.price, p0.price) AS price
FROM event e
INNER JOIN event_art ea ON e.id = ea.event_id
INNER JOIN art a ON ea
LEFT JOIN price p ON p.art_id = a.id AND p.cust_id = e.cust_id
LEFT JOIN price p ON p.art_id = a.id AND p.cust_id = 0