Find people who have the same day of birth - mysql

I'm looking for a way to create a query that gives me the list of people who were born on the same day (the data is in two different tables).
All ideas are welcome. ( I use MySQL)
SQL code :
https://pastebin.com/StNggaYg
CREATE TABLE Professeurs(
ID_Professeur Int Auto_increment NOT NULL ,
Nom_Professeur Varchar (50) NOT NULL ,
Prenom_Professeur Varchar (50) NOT NULL ,
Ville_de_naissance_P Varchar (50) NOT NULL ,
Date_de_naissance_P Date NOT NULL ,
Professeur_Principal Bool NOT NULL
,CONSTRAINT Professeurs_PK PRIMARY KEY (ID_Professeur)
)ENGINE=InnoDB;
#------------------------------------------------------------
# Table: Classes
#------------------------------------------------------------
CREATE TABLE Classes(
ID_Classes Int Auto_increment NOT NULL ,
Lettre_classe Char (5) NOT NULL ,
ID_Professeur Int NOT NULL
,CONSTRAINT Classes_PK PRIMARY KEY (ID_Classes)
,CONSTRAINT Classes_Professeurs_FK FOREIGN KEY (ID_Professeur) REFERENCES Professeurs(ID_Professeur)
)ENGINE=InnoDB;
#------------------------------------------------------------
# Table: Elèves
#------------------------------------------------------------
CREATE TABLE Eleves(
ID_Eleve Int Auto_increment NOT NULL ,
Nom_eleve Varchar (50) NOT NULL ,
Prenom_eleve Varchar (50) NOT NULL ,
Ville_de_naissance_E Varchar (50) NOT NULL ,
Date_de_naissance_E Date NOT NULL ,
ID_Classes Int NOT NULL
,CONSTRAINT Eleves_PK PRIMARY KEY (ID_Eleve)
,CONSTRAINT Eleves_Classes_FK FOREIGN KEY (ID_Classes) REFERENCES Classes(ID_Classes)
)ENGINE=InnoDB;
The column :
Date_de_naissance_E Date NOT NULL ,
Date_de_naissance_P Date NOT NULL ,

First, you would have to get the results of BOTH tables dates via a UNION to find what dates have more than one instance. Its possible to have two teachers with same date, two students with same date, OR a teacher AND student have same date. Once that is done, then you can join back to the respective original source to grab the names.
To simplify the query from rewriting it twice nested within itself, I will use CTE (common table expression). It allows you to write a query that will be used multiple times allowing simple alias name to be used in a subsequent query.
Below is the CTE via "With AllPeople as". This select is the query used in the second half. Notice I am getting ID, name, birth date and also a type "P" as Professeur and "E" as Eleves for the person type. First time through I am getting a count where a given birthdate occurs more than once. THEN, re-join to the same AllPeople again that had that date found as a common birth date.
with AllPeople as
( select
'P' personType,
p.ID_Professeur personID,
p.Nom_Professeur personName,
Date_Format( p.Date_de_naissance_P, "%M %d" ) commonDate
from
Professeurs p
union all
select
'E' personType,
e.ID_Eleve personID,
e.nom_eleve personName,
Date_Format( e.Date_de_naissance_E, "%M %d" ) commonDate
from
Eleves e
)
select
who.PersonType,
who.PersonID,
who.PersonName,
BornOnSameDay.commonDate
from
(select
commonDate
from
AllPeople
group by
commonDate
having
count(*) > 1 ) BornOnSameDay
JOIN
AllPeople Who
on BornOnSameDay.commonDate = Who.commonDate
order by
BornOnSameDay.commonDate,
who.PersonName
Now, you also provided a class table of which teachers were teaching what class, and if a student was in a particular class. If your intention was to find out which classes has a student with the same birthdate as the professor teaching it, that would be a different query.
Please advise on which you meant. The one I have provided is ANY teacher having a same birthday as ANY other teacher OR student. And likewise could be two students having the same birth date.

You can use the GROUP_CONCAT function:
SELECT date_format(birthdate,"%d %b") AS birthday, GROUP_CONCAT(person_name) AS people
FROM persons
GROUP BY MONTH(birthdate), DATE(birthdate)

Related

MySQL how to use check?

I am a very beginner in MYSQL and I am trying to use CHECK for EmployeeID is in the format of E### where "#" is the number(int). ANd the DOB that is eneterd should be 16 years or older from current date. Here is the code for the table. Thanks for help!
Create table Employee(
EmployeeID varchar(200) not null primary key,
DOB date,
##Check (DOB <= CURRENT_DATE - interval '16' year),
FirstName varchar(200),
MiddleName varchar(200),
LastName varchar(200),
Address varchar(255),
StartDate date,
Gender varchar(100)
);
I would use a regular expression to confirm the validity of the EmployeeID, such as this :-
EmployeeID varchar(200) not null primary key CHECK EmployeeID REGEXP 'E\d{3}',
Other answers covered using the check constraints.
However, if it's always going to start with an 'E', do you need to store the 'E'? Can you store just the integer and add the E later? An integer primary key is simpler, faster, smaller, and more robust.
Use a generated column to provide the ID with the E on it.
create table Employee (
-- No check required, it's an integer by definition.
-- Takes less storage to store and index.
ID integer primary key,
-- A generated virtual column (takes no storage space)
EmployeeID varchar(255) as (concat('E', id)) virtual
);
insert into Employee (id) values (1), (23), (456);
select * from Employee;
ID EmployeeID
1 E1
23 E23
456 E456
select * from Employee where EmployeeID = 'E456';
ID EmployeeID
456 E456
Try it.

View with derived value column

I'm having some trouble trying to make a view with a calculated average column, for every movie row I need an average rating based on all the ratings for this movie in the rating table.
Movie table:
CREATE TABLE IF NOT EXISTS streaming_db.movie(
id BIGINT NOT NULL auto_increment
,name VARCHAR (100)
,description VARCHAR (1000)
,PRIMARY KEY (id)
) engine = InnoDB;
Rating table:
CREATE TABLE IF NOT EXISTS streaming_db.rating(
id BIGINT NOT NULL auto_increment
,rating_score DECIMAL(4, 2) NOT NULL
,comment VARCHAR (255) NULL
,id_profile BIGINT NOT NULL
,id_movie BIGINT NOT NULL
,PRIMARY KEY (id)
) engine = InnoDB;
Here's what I have so far:
CREATE VIEW streaming_db.midia
AS
SELECT name,
description
FROM streaming_db.movie a
INNER JOIN (SELECT avg(rating_score) AS averageRating from streaming_db.rating where
rating.id_movie = a.id);
It was telling me that a derived table needs its own alias, and I don't know if that really gives me the average per row.
You are attempting a correlated subquery in the FROM clause. Well, this is actually a real thing, called a lateral join.
But that is not your intention. Move the logic to the SELECT:
SELECT m.name, m.description,
(SELECT avg(rating_score)
FROM sistema_streaming_db.rating r
WHERE r.id_movie = m.id
) as averageRating
FROM streaming_db.movie m;
Note that I fixed the table aliases so they are abbreviations for the table names, which makes the query much easier to read.

MySQL query between dates

I have the following table, where bookings can be made
CREATE TABLE booking (
bookingID INT UNSIGNED NOT NULL AUTO_INCREMENT,
customerID INT,
runID INT,
startDate DATETIME,
endDate DATETIME,
dateBookedOn TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (bookingID),
INDEX idx_start (startDate),
INDEX idx_end (endDate),
FOREIGN KEY (runID) REFERENCES RUn(RunID),
FOREIGN KEY (customerID) REFERENCES customer(CustomerID)
)
Then i have a run table
CREATE TABLE run
(
RunID INT UNSIGNED NOT NULL AUTO_INCREMENT,
RunName VARCHAR(15),
PricePerNight DECIMAL(3,2),
primary key (RunID)
);
I am querying the run table to get all runID's that do not lie between two dates in the booking table, as follows.
SELECT *
FROM run
WHERE Runid NOT IN (SELECT RunID
FROM booking
WHERE CAST(startDate AS DATE) >= '2015-07-19' AND
CAST(endDate AS DATE) <= '2015-07-25');
How would I change the query to select runID's that don't have ANY dates between them, if the dates overlap with query dates they are included in result set.
ie if a new booking had a startDate 2015-07-15 and a endDate 2015-07-21 then it will still show in the queries result set.
Your query does what you want, but might be a bit slow: Avoid NOT IN if you can. This should do the same but is just faster:
SELECT a.*
FROM run a
LEFT JOIN booking b ON a.runID=b.runID
AND startDate>= '2015-07-19' AND endDate<= '2015-07-25'
WHERE b.runID IS NULL;
Also avoid casting your data from your database: If you want/have to cast anything, cast your variables: Casting your variable=1 value cast, casting the data from your database is N values cast, plus that indexes can not be used anymore.

my SQL SELECT Columns From Multiple Tables Without Repeating Data

create table Student (
St_ID int not null,
St_Name varchar (100),
St_tel int,
St_ADD varchar (100) not null,
St_city varchar (100)not null,
St_type varchar (20) not null,
St_nationality varchar (20) not null,
Dep_ID int,
C_ID int,
primary key (St_ID),
foreign key (Dep_ID) references Department(Dep_ID),
foreign key (C_ID) references Course(C_ID),
)
create table Course (
C_ID int not null,
C_Name varchar (30) not null,
C_Duration varchar (10) not null,
DegreeType varchar (20),
Dep_ID int,
primary key (C_ID),
foreign key (Dep_ID) references Department (Dep_ID),
)
insert into Course Values (4040,'Software Engineering','18months','HND',001)
insert into Course Values (1454,'Business IT','6months','Diploma',001)
insert into Course Values (1534,'Business management ','18months','HND',002)
insert into Course Values (1245,'Digital Media','6months','Diploma',001)
insert into Course Values (1243,'Business Development','10months','Diploma',001)
INSERT INTO Student VALUES (1212,'jerome jacobs',0774750407,'no 66/7 senananyake lane ','nawala','fulltime','HND','SL',001,4040);
INSERT INTO Student VALUES (1713,'john paul',0773435646,'no 77/9 alvatigala lane','colombo ','parttime','Diploma','SL',001,1454);
INSERT INTO Student VALUES (1614,'Angelo mathews',0773436777,'no 88 rose lane colombo ','colombo 2','fulltime','HND','SL',002,1534);
INSERT INTO Student VALUES (1514,'jean paul',0713556688,'no 100/1 4th lane nawala','nawala','fulltime','Diploma','SL',002,1245);
INSERT INTO Student VALUES (1316,'Mark francis',0755657665,'no 54 1st lane ','kotte','parttime','HND','SL',003,4040);
INSERT INTO Student VALUES (1117,'Kevin steffan',0757667687,'no 99/5 railway lane ','nugegoda','parttime','Diploma','SL',004,1243);
SELECT DISTINCT Student.St_ID,St_Name,St_tel,St_ADD,St_type,DegreeType,C_Name from Student,Course where Student.St_type='parttime' and Course.DegreeType='HND';
this is my query to get information from two tables but it repeat values how can i fix that im really curious about sql im a beginner sorry for the way i ask questions i will be reall great full if it is answered
You have to JOIN the tables using the common field:
SELECT DISTINCT Student.St_ID,St_Name,St_tel,St_ADD,St_type,DegreeType,C_Name
from Student JOIN
Course ON Student.C_ID =Course.C_ID
where Student.St_type='parttime' and Course.DegreeType='HND';
An SQL JOIN clause is used to combine rows from two or more tables, based on a common field between them.
Read more about joins here.
You have to use MySql Join , if you need to understand it more : http://dev.mysql.com/doc/refman/5.0/en/join.html
You have to join the student and course tables together by specifying their common column (key). Instead of this:
from Student,Course
do this:
from Student
join Course on student.C_ID= Course.C_ID
If you don't connect the two tables properly you'll get the cartesian product set.
Click for Information JOIN
SELECT S.St_ID, St_Name, St_tel, St_ADD, St_type, DegreeType, C_Name
FROM Student s
INNER JOIN Course C ON S.C_ID = C.C_ID
WHERE S.St_type='parttime' and C.DegreeType='HND'
GROUP BY S.St_ID;

mysql data retrieval questions

rental table:
CREATE TABLE RENTAL
(
TransactionNo int NOT NULL AUTO_INCREMENT,
MemberID int NOT NULL,
ItemNo char(3) NOT NULL,
RentalEmployeeID varchar(30),
ReturnEmployeeID varchar(30),
Checkout_date DATE,
Checkin_date DATE,
Return_date DATE,
ItemQuantity int(11) NOT NULL,
TotalPrice DOUBLE(10,2) NOT NULL,
ItemFee DOUBLE(10,2),
PRIMARY KEY(TransactionNo),
FOREIGN KEY(MemberID) REFERENCES Member(MemberID),
FOREIGN KEY(ItemNo) REFERENCES Item(Itemno),
FOREIGN KEY(RENTALEMPLOYEEID) REFERENCES Employee(EmployeeID),
FOREIGN KEY(RETURNEMPLOYEEID) REFERENCES Employee(EmployeeID)
)
I am trying to retrieve the query for all of the customers that have purchased at least 2 items on the same day, however; i am still unable to accomplish it. Is a nested clause necessary for this?
my statement:
SELECT m.MemberID, r.`checkout_date`, SUM(r.itemquantity)
FROM RENTAL AS r, MEMBER AS m
WHERE r.MemberID = m.MemberID
GROUP BY m.MemberID, r.`checkout_date`
HAVING SUM (r.itemquantity) > 1
This new statement will give me what i want, however; because the rental information is not required(NULL) it sums up all of the return items as well and not the just rental.
You dont need a nested clause - 'GROUP BY' does the trick.
SELECT m.MemberID, r.`checkout_date`, COUNT(r.itemno)
FROM RENTAL AS r, MEMBER AS m
WHERE r.MemberID = m.MemberID
GROUP BY r.MemberID, `r.checkout_date`
group by memberid, checkoutdate having count(transactionid) > 1