USing Join Information to get the information from the table - sql

I am new to the SQL. I am learning joins in query so that i eterive the information from the table using information. I am working in this question .
Get the EmployeeNumber for the employees and the date they started any given department.
Below is my table definition :
CREATE TABLE Employees (
EmployeeID int IDENTITY(1,1) PRIMARY KEY
,EmployeeNumber int UNIQUE
,DateOfBirth datetime NOT NULL
,FirstName nvarchar(14) NOT NULL
,MiddleName nvarchar(14) NOT NULL
,LastName nvarchar(16) NOT NULL
,DateHired datetime NOT NULL
)
CREATE TABLE Customers (
CustomerID int IDENTITY(1,1) PRIMARY KEY
,FirstName nvarchar(14) NOT NULL
,MiddleName nvarchar(14) NOT NULL
,LastName nvarchar(16) NOT NULL
,DateLastVisited datetime NOT NULL
,EmailAddress nvarchar(52) NOT NULL
)
CREATE TABLE Departments (
DepartmentID int IDENTITY(1,1) PRIMARY KEY
,Code nchar(4) UNIQUE
,Name nvarchar(40) NOT NULL
)
CREATE TABLE DepartmentEmployees (
DepartmentEmployeeID int IDENTITY(1,1) PRIMARY KEY
,EmployeeID int NOT NULL
CONSTRAINT Department_Employee REFERENCES Employees(EmployeeID)
,DepartmentID int NOT NULL
CONSTRAINT Employee_Department REFERENCES Departments(DepartmentID)
,DateStarted datetime NOT NULL
,DateEnded datetime NOT NULL
)
CREATE TABLE Salaries (
SalaryID int IDENTITY(1,1) PRIMARY KEY
,EmployeeID int NOT NULL
CONSTRAINT Salaried_Employee REFERENCES Employees(EmployeeID)
,Amount money NOT NULL
,DateStarts datetime NOT NULL
,DateEnds datetime NOT NULL
)
I have added the information by inserting the data accordingly to the table.
For the question .
I have written this answer but i am not sure wether it is right or not.
SELECT e.EmployeeNumber,
d.DateStarted
FROM Employees e
Right
Join DepartmentEmployees d
on e.EmployeeID= d.DepartmentEmployeeID;

DepartmentEmployeeID is the primary key for the table department, you need to join the employee id's in both tables.
SELECT E.EmployeeNumber, D.DateStarted
FROM DepartmentEmployees D
LEFT JOIN Employees E
ON E.EmployeeID= D.EmployeeID;

Related

ALTER TABLE statement conflicted with the FOREIGN KEY constraint

When creating the foreign key I came across this error. Below is my code.
create table tblPerson(
ID int not null primary key,
Fullname varchar(50) not null,
Email varchar(50) not null,
GenderId int
)
create table tblGender (
ID int not null primary key,
Gender varchar(50) not null
)
alter table tblPerson add constraint tblPerson_GenderId_FK
foreign key (GenderId) references tblGender(ID)
You want to identify any "do not align" rows....
I have made the below.
You won't be able to add the FK constraint, if any rows come back from the SELECT query.
I have also removed the hungarian notation for "tbl". I would advise against it.
create table dbo.Person(
ID int not null primary key,
Fullname varchar(50) not null,
Email varchar(50) not null,
GenderId int )
create table dbo.Gender (
ID int not null primary key,
Gender varchar(50) not null
)
/* any rows below? your FK creation will fail */
Select *, p.GenderId as 'HoustonWeHaveAProblemValue' from dbo.Person p Where Not Exists (Select 1 from dbo.Gender g where g.ID = p.GenderId)
alter table dbo.Person add constraint Person_GenderId_FK
foreign key (GenderId) references dbo.Gender(ID)
Hi please use the following code to achieve your goal :
1-First create tblGender:
create table tblGender (
ID int not null primary key,
Gender varchar(50) not null
)
2-Then create table tblPerson with the relationship between 2 tables since the beginning:
create table tblPerson(
ID int not null primary key,
Fullname varchar(50) not null,
Email varchar(50) not null,
GenderId int references tblGender(ID)
)
works fine.

DateDiff asc and desc

SELECT DISTINCT
at.AccountId AS AccountId,
a.FirstName + ' ' + a.LastName AS [FullName],
DATEDIFF(day, T.ArrivalDate, T.ReturnDate) AS LongestTrip,
DATEDIFF(day, T.ArrivalDate, T.ReturnDate) AS ShortestTrip
FROM
Accounts a
JOIN
AccountsTrips at ON a.Id = AT.AccountId
JOIN
Trips t ON T.Id = AT.TripId
WHERE
a.MiddleName IS NULL AND t.CancelDate IS NULL
ORDER BY
DATEDIFF(day, T.ArrivalDate, T.ReturnDate) DESC, ShortestTrip ASC
The code only orders the tables descending in LongestTrip and in ShortestTrip
SAMPLE DATA !
Find the longest and shortest trip for each account, in days. Filter the results to accounts with no middle name and trips, which are not cancelled (CancelDate is null).
Order the results by Longest Trip days (descending), then by Shortest Trip (ascending).
Examples
AccountId FullName LongestTrip ShortestTrip
------------------------------------------------------------
40 Winna Maisey 7 1
56 Tillie Windress 7 1
57 Eadith Gull 7 1
66 Sargent Rockhall 7 1
69 Jerome Flory 7 2
… … … …
The Tables are --
CREATE TABLE Cities
(
Id INT PRIMARY KEY IDENTITY,
Name NVARCHAR(20) NOT NULL,
CountryCode CHAR(2) NOT NULL
)
CREATE TABLE Hotels
(
Id INT PRIMARY KEY IDENTITY,
Name NVARCHAR(30) NOT NULL,
CityId INT FOREIGN KEY REFERENCES Cities(Id) NOT NULL,
EmployeeCount INT NOT NULL,
BaseRate DECIMAL(10,2)
)
CREATE TABLE Rooms
(
Id INT PRIMARY KEY IDENTITY,
Price DECIMAL(10,2) NOT NULL,
Type NVARCHAR(20) NOT NULL,
Beds INT NOT NULL,
HotelId INT FOREIGN KEY REFERENCES Hotels(Id) NOT NULL
)
CREATE TABLE Trips
(
Id INT PRIMARY KEY IDENTITY,
RoomId INT FOREIGN KEY REFERENCES Rooms(Id) NOT NULL,
BookDate DATE NOT NULL, CHECK(BookDate<ArrivalDate),
ArrivalDate DATE NOT NULL, CHECK(ArrivalDate<ReturnDate),
ReturnDate DATE NOT NULL,
CancelDate DATE
)
CREATE TABLE Accounts
(
Id INT PRIMARY KEY IDENTITY,
FirstName NVARCHAR(50) NOT NULL,
MiddleName NVARCHAR(20),
LastName NVARCHAR(50) NOT NULL,
CityId INT NOT NULL,
BirthDate DATE NOT NULL,
Email VARCHAR(100) UNIQUE NOT NULL
CONSTRAINT FK_CityId FOREIGN KEY (CityId)
REFERENCES Cities(Id)
)
CREATE TABLE AccountsTrips
(
AccountId INT FOREIGN KEY REFERENCES Accounts(Id) NOT NULL,
TripId INT FOREIGN KEY REFERENCES Trips(Id) NOT NULL,
Luggage INT NOT NULL, CHECK(Luggage >= 0)
)
You want to pick the longest and shortest trips per account from your data. As all you want to get from the trips is the duration, you can simply aggregate and show MIN and MAX duration:
SELECT
a.Id AS AccountId,
a.FirstName + ' ' + a.LastName AS [FullName],
MIN(DATEDIFF(day, T.ArrivalDate, T.ReturnDate)) AS LongestTrip,
MAXD(ATEDIFF(day, T.ArrivalDate, T.ReturnDate)) AS ShortestTrip
FROM
Accounts a
JOIN
AccountsTrips at ON a.Id = AT.AccountId
JOIN
Trips t ON T.Id = AT.TripId
WHERE
a.MiddleName IS NULL AND t.CancelDate IS NULL
GROUP BY
a.Id, a.FirstName, a.LastName
ORDER BY
LongestTrip DESC, ShortestTrip ASC;
If you wanted to show additional data from the trips, you would use window functions (probably MIN OVER and MAX OVER) and would then either show two rows per account or aggregate these two rows.

Get count of games and display the players who played half of games

i Need help in these tables, i want SQL statement to give me this :
the players who played in half or more of the games, lets assume that we have 6 different games in 'GameType' table ... So I want to display all players who played 3 or more games.
like :
ID surName number of games played
1 test1 3
2 test2 4
3 test3 3
4 test4 6
this what i done until now:
SELECT dbo.Player.ID, dbo.Player.surName, count(DISTINCT
dbo.PlayerInAGame.gameTypeName) AS games_played, count(DISTINCT
dbo.Game.gameTypeName) AS games_count
FROM dbo.Player INNER JOIN
dbo.PlayerInAGame ON dbo.Player.ID =
dbo.PlayerInAGame.playerID INNER JOIN
dbo.Game ON dbo.PlayerInAGame.gameTypeName = dbo.Game.gameTypeName AND
dbo.PlayerInAGame.gameDateTime = dbo.Game.gameStartDateTime
GROUP BY dbo.Player.ID, dbo.Player.surName, dbo.Game.DealerInGame
here is the tables:
create table Dealer
(
number int identity(1000,1) primary key,
firstName nvarchar(20) not null,
surName nvarchar(20) not null,
birthDate date not null,
startWorkingDate date not null,
ID char(9) check(ID like replicate('[0-9]',9)) not null unique,
check(datediff(year,birthDate,startWorkingDate)>=24)
)
create table GameType
(
name nvarchar(20) primary key,
description nvarchar(20) not null,
minimumPlayers tinyint check (minimumPlayers > 0) not null,
maximumPlayers tinyint check (maximumPlayers > 0) not null,
check(minimumPlayers <= maximumPlayers)
)
create table Game
(
gameTypeName nvarchar(20) references GameType(name) on delete cascade,
gameStartDateTime datetime,
gameEndTime time,
DealerInGame int not null references Dealer(number),
primary key(gameTypeName,gameStartDateTime)
)
create table Player
(
ID char(9) primary key,
firstName nvarchar(20) not null,
surName nvarchar(20) not null,
city nvarchar(20) not null,
birthDate date check(datediff(year,birthDate,getdate())>=18) not null,
preferred nvarchar(20) references GameType(name) on delete set null
)
create table PlayerInAGame
(
playerID char(9) references Player(ID),
gameTypeName nvarchar(20),
gameDateTime datetime,
betAmount int check(betAmount>0) not null,
winLosAmount int,
check((winLosAmount = -betAmount) or (winLosAmount>=betAmount)),
foreign key(gameTypeName,gameDateTime) references
Game(gameTypeName,gameStartDateTime), primary
key(playerID,gameTypeName,gameDateTime) )
create table PlayerDealerRelation
(
dealerNumber int references Dealer(number) on delete cascade,
playerID char(9) references Player(ID),
relationType char(1) check(relationType in ('P','G','B','C','U','N')),
primary key(dealerNumber,playerID)
)
If your query in the question gives you the correct count, then it is very easy to add an extra filter that would leave only those rows where games_played is more than half of games_count.
Just add HAVING:
SELECT
dbo.Player.ID,
dbo.Player.surName,
count(DISTINCT dbo.PlayerInAGame.gameTypeName) AS games_played,
count(DISTINCT dbo.Game.gameTypeName) AS games_count
FROM
dbo.Player
INNER JOIN dbo.PlayerInAGame ON dbo.Player.ID = dbo.PlayerInAGame.playerID
INNER JOIN dbo.Game
ON dbo.PlayerInAGame.gameTypeName = dbo.Game.gameTypeName
AND dbo.PlayerInAGame.gameDateTime = dbo.Game.gameStartDateTime
GROUP BY dbo.Player.ID, dbo.Player.surName, dbo.Game.DealerInGame
HAVING
count(DISTINCT dbo.PlayerInAGame.gameTypeName) >
count(DISTINCT dbo.Game.gameTypeName) / 2

SQL Server 2012 : Create Table

CREATE TABLE Schedule
(
Section DATETIME NOT NULL PRIMARY KEY(CourseID, Section, EmployeeID),
CourseID VARCHAR(10) REFERENCES Course(CourseID) NOT NULL,
EmployeeID VARCHAR(20) NOT NULL REFERENCES Employee(EmployeeID),
StartTime TIME NULL,
Days DATE NULL,
Length TIME NULL
)
CREATE TABLE Enrollment
(
StudentID INT Primary key (StudentID, CourseID, Section) NOT NULL,
CourseID VARCHAR(10) REFERENCES Course(CourseID) NOT NULL,
Section DATETIME NOT NULL REFERENCES Schedule(Section)
)
2nd table did not get created, where did I go wrong?
Its because you made the primary key in the Schedule table a natural/combined key.
Try creating a stand alone column for this purpose instead. I've included an example below that shows the differences.
CREATE TABLE DBO.PK_TEST (
Col_A INT NOT NULL
,Col_B INT NOT NULL
,Primary Key(Col_A,Col_B)
)
Create table DBO.PK_TEST_2 (
Col_A int NOT NULL
,Col_B int NOT NULL
,Col_C as (cast(Col_A as nvarchar)
+ cast(Col_B as nvarchar)) PERSISTED NOT NULL
,primary key(Col_C)
)

SQL How to convert this to a SubQuery?

Learning, be kind.
I am trying to understand how this works and I have done several successful conversions, but this one I am stumped on.
How do I take this code and convert it to a subquery? I'm a little lost.
SELECT o.FirstName + ' ' + o.LastName AS Driver, COUNT(DISTINCT s.vehicleID) NoOfBusesUsed
FROM Operators AS o, Runs AS r, Schedules AS s JOIN Trips AS t
ON s.scheduleID = t.scheduleID
WHERE r.BidDate BETWEEN '09/01/2004' AND '09/30/2004'
GROUP BY o.FirstName + ' ' + o.LastName
HAVING COUNT(s.vehicleID) > 1
Here is how my tables are setup. If more info is needed, I can post.
CREATE TABLE Operators
(
SeniorityNumber char(4) NOT NULL
CONSTRAINT ck_Operators_Seniority
CHECK (SeniorityNumber LIKE '[0-9][0-9][0-9][0-9]'),
FirstName varchar(25) NOT NULL,
LastName varchar(35) NOT NULL,
HireDate smalldatetime
CONSTRAINT ck_Operators_HireDate CHECK (HireDate <=Getdate())
)
CREATE TABLE Trips
(
RouteNumber varchar(4) NOT NULL,
StartLocation varchar(50) NOT NULL,
StartTime time NOT NULL,
EndLocation varchar(50) NOT NULL,
EndTime time NOT NULL,
EffectiveDate smalldatetime NOT NULL
CHECK (EffectiveDate >= cast('1/1/2000' as smalldatetime)),
CONSTRAINT ck_Trips_StartEnd CHECK (EndTime > StartTime)
)
CREATE TABLE Vehicles
(
Manufacturer varchar(50)
DEFAULT 'Gillig',
Model varchar(50),
ModelYear int
DEFAULT DatePart(yyyy,GetDate())
CHECK (ModelYear <= DatePart(yyyy,GetDate())),
PurchaseDate smalldatetime
)
GO
ALTER TABLE operators
ADD OperatorID int IDENTITY --Primary Key
GO
ALTER TABLE Operators
ADD CONSTRAINT pkOperators Primary key (OperatorID)
ALTER TABLE Vehicles
ADD VehicleID int IDENTITY Primary Key
ALTER TABLE Trips
ADD TripID int IDENTITY Primary key
GO
CREATE TABLE Runs
(
RunID int IDENTITY NOT NULL Primary Key,
OperatorID int NOT NULL REFERENCES Operators,
BidDate date NOT NULL
CONSTRAINT ckRunBidDate CHECK
(biddate <= dateadd(mm,6,getdate())) --getdate() + 180
)
GO
CREATE TABLE Schedules
(
ScheduleID int IDENTITY Primary Key,
RunID int NOT NULL,
VehicleID int NOT NULL,
CONSTRAINT fk_Schedules_Runs FOREIGN KEY (RunID)
REFERENCES Runs(RunID),
CONSTRAINT fk_Schedules_Vehicles FOREIGN KEY (VehicleID)
REFERENCES Vehicles
)
ALTER TABLE Trips
ADD ScheduleID int NULL REFERENCES Schedules
When you want to use a query as a sub-query you can use WITH statement or a derived table like:
With:
;WITH subQuery AS (
/* Your query here */
)
SELECT *
FROM subQuery
Derived table
SELECT *
FROM (
/* your query here */
) As subQuery
I think you should use a query like this:
SELECT
o.FirstName + ' ' + o.LastName AS Driver,
DT.cnt AS NoOfBusesUsed
FROM
Operators AS o
JOIN
(SELECT
r.OperatorID,
COUNT(DISTINCT s.VehicleID) AS cnt
FROM
Schedules s
JOIN
Runs r ON s.RunID = r.RunID
) AS DT
ON DT.OperatorID = o.OperatorID
WHERE
ISNULL(DT.cnt, 0) > 1