Relational databases SQL: Parent/Child relationships - mysql

I am trying to learn SQL. I have three different tables. All the tables have one common column. I am showing a very small portion of sample data.
I am trying to understand how to read from a parent table after a child table has been updated.
Table_1 (booking platform info)
booking_date column2 column3 column4 cust_country_id hotel_id booking_value
22-mar-2016 .................. 1001 1 $150
01-apr-2016 .................. 1002 2 $500
09-apr-2016 .................. 1001 2 $222
17-apr-2016 .................. 1002 4 $75
19-apr-2016 .................. 1003 1 $690
03-May-2016 ................., 1001 3 $301
Table_2 (hotel information)
hotel_id hotel_name hotel_country
1 Marriott Germany
2 Novotel France
3 Oberoi India
4 Osaka Japan
Table_3 (customer information)
country_id country_name
1001 India
1002 France
1003 Japan
My question is if a new hotel Hyatt from France is added to Table_2 (hotel information), how can I find out the first date at which a French customer booked that hotel?
I am getting a bit confused on how to approach this; as it has to take values from all 3 tables.

I think in this case you should write mysql query to find the oldest booking_date for customer from France and hotel with name Hyatt
select booking_date from Table_1
join Table_2 on Table_2.hotel_id = Table_1.hotel_id
join Table_3 on Table_3.country_id = Table_1.cust_country_id
where Table_3.country_name = 'France' and Table_2.hotel_name = 'Hyatt'
order by Table_1.booking_date asc
limit 1

Related

need output with sub query from the tables in mysql

FROM THE GIVEN TABLES: Teacher And Student
teacher_ID name city fee
------------------- ------------------------
1 Jit New York 15000
2 Nilon Paris 13000
5 Pol London 11000
6 Maj Paris 14000
7 Paul Rome 13000
3 Liza Saudi 12000
----------------------------------------------------------
student_id name city rank teacher_ID
2 Nick New York 1 1
7 Brady New York 2 1
5 Gunman California 2 2
8 Juli London 3 2
4 Faral Paris 3 6
9 Goku Berlin 1 3
3 John Moscow 2 7
1 Badstar London 5
From the Given Tables I need to make a list in ascending order for the students who holds a rank less than 3 and taught either by a teacher or by own.
It's expected output is this
name city rank Teacher city
Nick New York 1 Jit New York
John Moscow 2 Paul Rome
Gunman California 2 Nilon Paris
Brady New York 2 Jit New York
Goku Berlin 1 Liza Saudi
I tried writing sql code
SELECT name,city,rank FROM Student WHERE rank < 3 ORDER BY student_ID ASC;
That code gives me first 3 columns of the expected output however I've no idea how to get the last two column of the expected output, any suggestions are welcome
The query...
SELECT Student.name,
Student.city,
rank,
Teacher.name as "Teacher",
Teacher.city
FROM Student
LEFT JOIN Teacher on Teacher.teacher_ID = Student.teacher_ID
WHERE rank < 3
ORDER BY student_ID ASC;
There are a few things that you should consider in the statement
When selecting the fields you want to display you need to make sure table column references are unique. As both tables have the field name and city, you should specifically reference them using the format of [table].[column name]
There are multiple ways that you can join tables. In this case, you want to use a left join because all data exists in the tables on the left side of the join, and might not exist in the table on the right side of the join.
If the student has a result of less than 3 and no teacher, the teacher name and city will appear as null. You might want to consider adding an IFNULL or similar to make these fields clear.

How to select rows with same values in one column but all must be different between each other in another column

Hello everyone i will try to be as specific and precise as possible.
I was looking around for answer to my problem and in mean time i made 2 tables
In first table i have names of Companies and their id-s.
In second table i have names of Employees,their id-s,the cities in which they live,and idK-s(its supposed to match id id-s from previous table) of Companies they work in.
I am supposed to select names of Companies that have at least four(3 or more) employees living in different cities compared to each other.
In order for things to be more clear i am going to give an example:
table1:
id name
1 Company1
2 Company2
3 Company3
4 Company4
5 Company5
6 Company6
table2:
id name city idK
1 EMP1 city1 1
2 EMP2 city2 1
3 EMP3 city3 1
4 EMP4 city4 1
5 EMP5 city1 2
6 EMP6 city2 2
7 EMP7 city3 2
8 EMP8 city1 3
9 EMP9 city2 3
10 EMP10 city3 3
11 EMP11 city1 4
12 EMP12 city2 4
13 EMP13 city3 4
14 EMP14 city4 4
15 EMP15 city5 4
16 EMP16 city1 5
17 EMP17 city2 5
18 EMP18 city1 5
19 EMP19 city3 5
20 EMP20 city3 5
21 EMP21 city2 5
22 EMP22 city1 6
23 EMP23 city8 6
24 EMP24 city1 6
25 EMP25 city15 6
I made spaces so it is easier to see.
So in idK=1 we have four employees and all are from different city compared to each other so Company1 should be in results.
idK=2 and idK=3 have under four employees in general so Company2 and Company3 are out.
idK=4 is good same reasons as idK=1 but idK=5 and idK=6 are out because while they have four or more employees they are not from different cities compared to each other.
I found similar problems as mine and some solutions but none were good enough for me or i just couldn't make them work so i would be very grateful if someone could explain to me what to do in this situation.
This will work here.
select t1.name from table2 t2
inner join table1 t1 on t2.idK = t1.id
group by t2.idk,t1.name
having count(distinct city) > 3
This is the data I used to test on db-fiddle.
CREATE TABLE table2 (id int, name varchar(100), city varchar(100), idK int);
INSERT INTO table2 (id,name,city,idK)
VALUES (1,'EMP1','city1',1),
(2,'EMP2','city2',1),
(3,'EMP3','city3',1),
(4,'EMP4','city4',1),
(5,'EMP5','city1',2),
(6,'EMP6','city2',2),
(7,'EMP7','city3',2),
(8,'EMP8','city1',3),
(9,'EMP9','city2',3),
(10,'EMP10','city3',3),
(11,'EMP11','city1',4),
(12,'EMP12','city2',4),
(13,'EMP13','city3',4),
(14,'EMP14','city4',4),
(15,'EMP15','city5',4),
(16,'EMP16','city1',5),
(17,'EMP17','city2',5),
(18,'EMP18','city1',5),
(19,'EMP19','city3',5),
(20,'EMP20','city3',5),
(21,'EMP21','city2',5),
(22,'EMP22','city1',6),
(23,'EMP23','city8',6),
(24,'EMP24','city1',6),
(25,'EMP25','city15',6);
Create TABLE table1 (id int,name varchar(100));
INSERT INTO table1 (id,name)
VALUES (1,'Company1'),
(2,'Company2'),
(3,'Company3'),
(4,'Company4'),
(5,'Company5'),
(6,'Company6');
You can use count(DISTINCT columnname) to get the number of unique values in a column.
SELECT
c.`name`,
COUNT(DISTINCT e.`city`) as `Num Cities`
FROM `companies` c
JOIN `employees` e
ON c.`id` = e.`idK`
WHERE COUNT(DISTINCT e.`city`) > 3
GROUP BY c.`name`
ORDER BY c.`name`
I expect this is what you are looking for
select idk
from table2
group by idk
having count(distinct city) > 3

SQL QUERY ON EXISTS CLAUSE

1) Query:
SELECT INS_NAME
FROM INSTRUCTOR
WHERE EXISTS(SELECT DEPT_NAME
FROM DEPARTMENT
WHERE DEPT_ID = INSTRUCTOR.DEPT_ID AND DEPT_BUILDING = 'JOHNS');
2) Query:
SELECT INS_NAME
FROM INSTRUCTOR
WHERE EXISTS(SELECT DEPT_NAME
FROM DEPARTMENT
WHERE DEPT_BUILDING = 'JOHNS');
codes 1 and 2 produce different outputs please help me understand the reason.
(INSTRUCTOR TABLE)
ins_id ins_name dept_id ins_sal tax
27 DHIRAJ 4 200
28 RAHUL 4 500
34 HIO 4 100 2
90 SURYA 5 120 30
33 VINNY 6 100 11
(DEPARTMENT TABLE)
DEPT_BUILDING DEPT_NAME DEPT_ID
THOMAS BIO 4
JOHNS CHEM 5
JOHNS CSE 6
The second query returns all records from the instructor table because there are 2 records in the department table where DEPT_BUILDING='JOHNS'. Thus the exists() returns true for every record.
The first query returns only the last 2 records from the instructor table because the exists() also tests for a match in the department id and department no 4 does not have a building called johns.

How to multiple concatenate values from multiple relation tables in a single mysql query

I have a big issue for my "traveling offer" project, working 99% OK, but not 100%.
I have main table with offers, where each offer can have set multiple department cities as well as multiple destination cities (this is reduced sample with reduced columns).
For example, I'm offering some travels from England, where department cities can be from London, Leeds and Manchester. Destination cities are Prague, Bratislava, Budapest and Belgrade.
Offer 1 is set to department cities London or Leeds, and destinations are Prague and Budapest.
Offer 2 is set to department city London, and destinations are Bratislava and Belgrade.
Offer 3 is set to department city Manchester or Leeds, and destination is Prague.
Table offers
----------------------------
id title price
----------------------------
1 Offer 1 title 300 Eur
2 Offer 2 title 250 Eur
3 Offer 3 title 350 Eur
Now relation tables and city name tables
Table departments
----------------------------
id name
----------------------------
1 London
2 Leeds
3 Manchester
relation Table rel_departments
------------------------
offer_id rel_id
------------------------
1 1
1 2
2 1
3 2
3 3
Table destinations
----------------------------
id name
----------------------------
1 Prague
2 Bratislava
3 Budapest
4 Belgrade
relation Table rel_destinations
------------------------
offer_id rel_id
------------------------
1 1
1 3
2 2
2 4
3 1
As SQL result I expect for each offer concatenated values bot for department cities and destination cities
If I search all with following sql I got OK result:
SELECT offers.*,
GROUP_CONCAT(DISTINCT DEPC.name SEPARATOR ', ') AS depCities,
GROUP_CONCAT(DISTINCT DESTC.name SEPARATOR ', ') AS destCities
FROM offers
INNER JOIN `rel_departments` ON (`rel_departments`.`offer_id` = `offers`.`id`)
INNER JOIN `departments` as DEPC ON (DEPC.`id` = `rel_departments`.`rel_id`)
INNER JOIN `rel_destinations` ON (`rel_destinations`.`offer_id` = `offers`.`id`)
INNER JOIN `destinations` as DESTC ON (DESTC.`id` = `rel_destinations`.`rel_id`)
GROUP BY offers.id
result would be okay:
---------------------------------------------------------------------
id title price depCities destCities
---------------------------------------------------------------------
1 Offer 1 title 300 Eur London, Leeds Prague, Budapest
2 Offer 2 title 250 Eur London Bratislava, Belgrade
3 Offer 3 title 350 Eur Leeds, Manchester Prague
And I need results like this whatever WHERE clause is. But, whenever I put where clause, I loose one of results in concatenation. For example, I search for all offers with Prague as a destination. If I add to the end of the sql statement:
where rel_destinations.rel_id=1
result is as following:
---------------------------------------------------------------------
id title price depCities destCities
---------------------------------------------------------------------
1 Offer 1 title 300 Eur London, Leeds Prague
3 Offer 3 title 350 Eur Leeds, Manchester Prague
If you can notice, there is no Budapest in offer 1. What to do to get complete concatenation string... Not that WHERE clause can be more complex, i.e. to search for department city or any other parameter.
Any help is appreciated :)
You need to use a different join with rel_destinations to get the offers with Prague as a destination. Join this with your original query.
SELECT offers.*,
GROUP_CONCAT(DISTINCT DEPC.name SEPARATOR ', ') AS depCities,
GROUP_CONCAT(DISTINCT DESTC.name SEPARATOR ', ') AS destCities
FROM offers
INNER JOIN `rel_departments` ON (`rel_departments`.`offer_id` = `offers`.`id`)
INNER JOIN `departments` as DEPC ON (DEPC.`id` = `rel_departments`.`rel_id`)
INNER JOIN `rel_destinations` ON (`rel_destinations`.`offer_id` = `offers`.`id`)
INNER JOIN `destinations` as DESTC ON (DESTC.`id` = `rel_destinations`.`rel_id`)
INNER JOIN rel_destinations AS d1 ON d1.offer_id = offers.id
WHERE d1.rel_id = 1
GROUP BY offers.id
DEMO

In mysql how can I identify duplicate field values and append incremental numbers to each one

So guys, I really do need help with this one:
I have this table:
---------------
mytable
---------------
id col1
1 Winston Churchill
2 Mahatma Ghandi
3 Nnamdi Azikiwe
4 John Kennedy
5 John Paul II
6 Nelson Mandela
7 John Kennedy
8 Mikhail Gorbachev
9 John Kennedy
What I want to do is find rows with duplicated col1 and for each of them, append incremental numbers to the value of col. In the end, we should be left with this:
---------------
mytable
---------------
id col1
1 Winston Churchill
2 Mahatma Ghandi
3 Nnamdi Azikiwe
4 John Kennedy 1
5 John Paul II
6 Nelson Mandela
7 John Kennedy 2
8 Mikhail Gorbachev
9 John Kennedy 3
The problem of the duplicate col1 is only a part of your problem ..
but if you don't want a trigger or a server side procedure you can try the follow query .
You should repeat this command as many times as the maximum number of repetitions ..
From time to time the repetition with the highest id receives a value equal to count, and the next repetition time being the new name is not counted
update my_table as a
inner join (
select col1, count(*) as num, max(id) as id
from my_table
group by col1
having count(*) >1 ) t on a.col1 = t.col1 and a.id = t.1
set a.col1 = concat( a.col1, ' ', t.num )