Database Merging Tables - mysql

I just want to ask how to merge two tables.
Because I have a table guest and company both of them acquire a reservation.
I want to join both of them and label them as customers and I want to add a new column customer type which will say guest, if my company is null... and company, if my guest is null...
Here's an example:
guest(g_id(PK), name, guest details etc....)
company(c_id(PK), name, company details etc...)
reservation(r_id(PK), g_id(fk), c_id(fk), reservation details etc...)
When I join them (assuming guest has acquired a reservation) my table looks like
reservation_id|company name|guest name|reservation details
1 null <name> <details>
2 null <name> <details>
What I want is to make it like this:
reservation_id|customer name|cust_type|reservation details
1 <name> <guest> <details>
2 <name> <company> <details>

One possible solution would be to first create a query for each type of reservation (which you might already have) and add the cust_type there, then union the two together. So the initial queries would be something like:
guest_reservations:
SELECT reservation.r_id, guest.name, "guest" AS cust_type, {other fields}
FROM guest, reservation INNER JOIN guest ON guest.g_id = reservation.g_id;
company_reservations:
SELECT reservation.r_id, company.name, "company" AS cust_type {other fields}
FROM company, reservation INNER JOIN company ON company.c_id = reservation.c_id;
Then you could union the two queries together, something like below.
SELECT reservation.r_id, guest.name, "guest" AS cust_type, {other fields}
FROM guest, reservation INNER JOIN guest ON guest.g_id = reservation.g_id
UNION SELECT reservation.r_id, company.name, "company" AS cust_type {other fields}
FROM company, reservation INNER JOIN company ON company.c_id = reservation.c_id;
Of course remember to either remove {other fields} or add in whatever else you need there.

Not sure the schema is the best but consider the following tables:
Res (resId, description, cid, gid, details)
1 Guest Res 1 NULL Just some guy
2 Comp Res NULL 1 Corporate jerk
Guest (gid, name)
1 Chuck
Company (cid, name)
1 Tenth
Check out the parameters of the select query:
1. r.rid : id of reservation table
2. isnull(c.name, g.name) : gets the non null value from either company or guest
3. isnull(replace(c.name, c.name, 'Company'), 'Guest') as type
Fanciness...if c.name is something, then 'Company', otherwise 'Guest'
4. r.details : reservation details
You need the outer join because of the nulls, this gives you a complete view of your data.
left outer join company c on r.cid = c.cid
left outer join guest g on r.gid = g.gid
So if you stick it all together you get what you are looking for:
select r.rid, r.description, isnull(c.name, g.name),
isnull(replace(c.name, c.name, 'Company'), 'Guest') as type,
r.details from res r
left outer join company c on r.cid = c.cid
left outer join guest g on r.gid = g.gid
1 Guest Res Chuck Guest Just some guy
2 Comp Res Tenth Company Corporate jerk

Related

Why does my Query return "Empty set (0.00 sec)"?

SOLVED-run UPDATE building SET building_name = "Main Street Building" WHERE building_id = 2;
From there, the task 3 query will return proper results.
Task One:
Query:
SELECT first_name, last_name, building_name, room.room_id, meeting_start,meeting_end
FROM meeting, person, person_meeting,room, building
WHERE room.room_id=meeting.room_id
AND meeting.meeting_id=person_meeting.meeting_id
AND person.person_id=person_meeting.person_id
AND room.building_id=building.building_id
AND person.first_name='Tom'
AND person.last_name='Hanks';
Task Two:
Query:
SELECT first_name, last_name, building_name, room.room_id, meeting_start,meeting_end
FROM meeting, person, person_meeting,room, building
WHERE room.room_id=meeting.room_id
AND meeting.meeting_id=person_meeting.meeting_id
AND person.person_id=person_meeting.person_id
AND room.building_id=building.building_id
AND meeting.meeting_id=2;
Task Three:
Query:
SELECT first_name, last_name, building_name, room.room_id,meeting.meeting_id, meeting_start, meeting_end
FROM meeting, person, person_meeting,room, building
WHERE room.room_id=meeting.room_id
AND meeting.meeting_id=person_meeting.meeting_id
AND person.person_id=person_meeting.person_id
AND room.building_id=building.building_id
AND building_name='Main Street Building';
Task Four:
Query:
SELECT count(person_id) 'Count of meeting attendees', meeting.meeting_id,meeting_start,meeting_end
FROM meeting, person_meeting
WHERE meeting.meeting_id=person_meeting.meeting_id
GROUP BY meeting.meeting_id;
Task Five:
Query:
SELECT first_name, last_name, meeting.meeting_id, meeting_start, meeting_end
FROM meeting INNER JOIN person_meeting ON meeting.meeting_id=person_meeting.meeting_id
INNER JOIN person ON person.person_id=person_meeting.person_id
AND meeting_start<'2016-12-25 12.00.00';
Task 1,2,4,5 and 5 all run perfectly. if you all need the task prompts, let me know.
Note: I haven't test this yet.
I changed the queries based on our recent interaction.
This is your original
SELECT first_name, last_name, building_name, room.room_id,meeting.meeting_id, meeting_start, meeting_end
FROM meeting, person, person_meeting,room, building
WHERE room.room_id=meeting.room_id
AND meeting.meeting_id=person_meeting.meeting_id
AND person.person_id=person_meeting.person_id
AND room.building_id=building.building_id
AND building_name='Main Street Building';
This is the way I would try to build it
Based on page 2 and 3 in the document, you provided, https://snhu.brightspace.com/d2l/lor/viewer/viewFile.d2lfile/76437/9523,2/, I would do the following:
First, I would obtain information about the building.
SELECT building_id
FROM building
WHERE building_name like '%Main Street Building%';
Note: I am assuming that the building name is correct. However, just in case, I am using the wildcard % before and after the name
Next, I would obtain the information about the room:
SELECT b.building_name, r.room_id
FROM room r
LEFT JOIN building b
ON r.building_id = b.building_id
WHERE b.building_name like '%Main Street Building%';
Following that, I would obtain the information about the meeting:
SELECT b.building_name, r.room_id, m.meeting_id, m.meeting_start, m.meeting_end
FROM room r
LEFT JOIN building b
ON r.building_id = b.building_id
LEFT JOIN meeting m
ON r.room_id = m.room_id
WHERE b.building_name like '%Main Street Building%';
Finally, I would obtain the information of the IDs of people that will be in that meeting and show their names:
SELECT b.building_name, r.room_id, m.meeting_id, m.meeting_start, m.meeting_end, p.first_name, p.last_name
FROM room r
LEFT JOIN building b
ON r.building_id = b.building_id
LEFT JOIN meeting m
ON r.room_id = m.room_id
LEFT JOIN persom_meeting pm
ON m.meeting_id = pm.meeting_id
LEFT JOIN person p
ON pm.person_id = p.person_id
WHERE b.building_name like '%Main Street Building%';
If by any chance, these queries do not work, I would advice that you ensure that the relationships exists between the tables.
This means that there should be a building_id match, a room_id match, a meeting_id match and a person_id match between the tables. Plus, I would check that the building name is spelled correctly since its case-sensitive.
The reason I use LEFT JOINs is so I can display all the information of the previous tables (all the rows) plus the records in which the IDs match the foreign keys IDs. As explained here: http://www.acarlstein.com/?p=4168
Also, in http://www.acarlstein.com/?p=4194, I am showing how a Two Left (Outer)Joins would work.
However, in your case, it is more like a chain that is being build so it doesn't match the diagram but you can perhaps get the idea of what I mean.

How to apply conditional join in EF Core?

Let's say I have a table Contacts, Customers, and Suppliers. Contacts has a column ContactTypeId and ExternalContactId. So you could end up with either:
var extContacts = from ct in _context.Contacts
join cu in _context.Customers
on ct.ExternalContactId equals cu.Id
Or I could have this as well
var extContacts = from ct in _context.Contacts
join su in _context.Suppliers
on ct.ExternalContactId equals su.Id
Here, I've showed only 2 joins to illustrate my point. In my case, I have 5 tables.
Is there any way, I can make just one call, join Contacts table depending on the ContactTypeId? Otherwise I may have to make more than 1 call (up to 5).
Something like:
var extContacts = from ct in _context.Contacts
join (
//if type is Customer --> Join with Customers table
//if type is supplier --> join with Suppliers table
)
select name, phone, address //fields common to both tables
Thanks for helping

Sql query join on not eqal

So i have this relational model for hospital (not made by me).
Patient (has an adress and an id), hospital (has id and address), and also there's a table for relationship representing placement in the hospital (hospital.id, patient.id) (also there's other tables, but they don't matter in this query);
The purpose of the query is to find hospitals where is no placed patients from from other cities than hospital's one (on condition that address only contains city).
The problem that i have is theoretical, i don't really know if to use full outer join with a or b null, or something else in the query that finds hospitals containing "foreign" patients, (like join hospital with its placement and then full outer join with a or b table record null, but that leads to a question will i get results in the query? Because i need cities that don't match but all the explanations of that join are about .
Thanks to all who embraced my utterly imperfect english and understood it.
Upd.
Patient:
id=1, city =A;
id=2, city =B;
id=3, city =B;
id=4, city =A;
id=5, city =C;
Hospital:
Id =1, city=A
id =2, city=B;
Placement:
h.id p.id
1 1
1 4
2 2
2 3
2 5
Expected results is "1", id of the first hospital (where's no patients from other city) and others with that "feature"
my query is like
select id from hospital where id not in
(select id,address from hospital inner join placement on h.id=placement.h.id as b inner join patient on placement.p.id=p.id where hospital.address<>patient.address )
Sorry for the delay
Is shawn's query correct?
Can i use h.id instead 1? Idk if our teacher would accept that, because he's never showed us something like that and in 10 years he hasn't managed to create an example of that database for students to test queries on.
select * from hospitals h
where not exists (
select 1 -- dummy value, use h.id if you prefer
from patients p inner join placement pl on pl.pid = p.id
where pl.hid = h.id and p.city <> h.city
)
or
select h.id
from hospitals h
left outer join
placement pl inner join patients p on p.id = pl.pid
on pl.hid = h.id
group by h.id
-- this won't count nulls resulting from zero placements for that hospital
-- as long as standard sql null comparisons are active
having count(case when h.city <> p.city then 1 end) = 0
Looks like it works to me: http://rextester.com/BTJB59061

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'
);

MySQL, Show value of column if match exist else leave as null

I'm sure this has been asked before but can't find the answer.
I have 3 tables OWNER, CAR, HOUSE
OWNER has 2 columns id and name
CAR has 3 columns id, ownerId and cartype
HOUSE has 4 columns id, ownerId, address, country
I want to write a SQL query that gets the owners name, cartypes, and addresses that are in Sweden
Here comes the tricky part. I want all the owners names and cartypes in the result table even if they don't own a house in Sweden. Can I get all that in 1 query or do I need to use 2? How would that query look?
You should be able to accomplish this with a simple left join:
SELECT O.name, C.cartype, H.address, H.country
FROM OWNER AS O
JOIN CAR AS C ON O.id = C.ownerid
LEFT JOIN HOUSE AS H ON O.id = H.ownerid AND Ucase(H.country) = "SWEDEN"
This will always give you a list of owners and their car types, in addition, it will give you a list of those that also happen to have a house address in sweden.
First you need to join the table then add new column in query by using CASE to check
SELECT o.* , c.* ,h.*,
(CASE WHEN h.county ='sweden' THEN h.county ELSE NULL END) AS HasCountry
FROM OWNER o
JOIN CAR c ON (c.ownerId =o.id)
JOIN HOUSE h ON (h.ownerId =o.id)