Referencing the primary table in a sub-query - sql

I have tables with some relations:
create table Students
(
[id] uniqueidentifier not null,
primary key (id),
[group] uniqueidentifier FOREIGN KEY REFERENCES [Groups]([id]) not null,
[name] nvarchar(20),
[surname] nvarchar(20)
)
create table Books
(
[id] uniqueidentifier not null,
primary key (id),
[name] nvarchar(100) not null,
[pages] int not null,
[author] uniqueidentifier FOREIGN KEY REFERENCES [Authors]([id])
)
create table StudentsCards
(
[id] uniqueidentifier not null,
primary key (id),
[student] uniqueidentifier FOREIGN KEY REFERENCES [Students]([id])
)
create table RelationsBooksToStudentsCards
(
[book] uniqueidentifier FOREIGN KEY REFERENCES [Books]([id]) not null,
[students_card] uniqueidentifier FOREIGN KEY REFERENCES [StudentsCards]([id]) not null
)
And I have query which trying to get sum of pages by students:
SELECT
[id] AS student_id, [name], [surname],
(SELECT SUM(b.pages)
FROM Students AS s
INNER JOIN RelationsBooksToStudentsCards AS r ON (SELECT [id] FRM StudentsCards WHERE student = s.id) = r.students_card
INNER JOIN Books AS b ON r.book = b.id
WHERE s.id LIKE student_id)
FROM
Students
Question: what do I need to do to use student_id in the query? Because now I got an exception:
Invalid column name 'student_id'

Ah, it was easy:
select [id], [name], [surname], (SELECT sum(b.pages)
FROM Students as s
inner JOIN RelationsBooksToStudentsCards as r
ON (select [id] from StudentsCards where student = s.id) = r.students_card
inner JOIN Books as b
ON r.book = b.id
where s.id like myAlias.id) from Students as myAlias

Related

How to combine two selects with same value but not the same INNER JOIN

I have to need a project school, a site like ebay
with bid.
I have to make a select who select
the name of the seller
the name of the last "customer" (bid)
BUT THE PROBLEM is that there two value was in the same table, so for access to the value I need to make 2 select with different INNER JOIN (look the diag for understand)
I have made two selects but I don't understand how to make a single select.
SELECT nom AS nameSeller
FROM ENCHERES e
INNER JOIN ARTICLES_VENDUS ac ON ac.no_article = e.no_article
INNER JOIN UTILISATEURS u ON u.no_utilisateur = ac.no_utilisateur
WHERE nom_article LIKE '%ta%'
SELECT nom AS nameCustomer
FROM ENCHERES e
INNER JOIN UTILISATEURS u ON e.no_utilisateur = u.no_utilisateur
WHERE e.no_utilisateur= 57
what i have with two select
First select
nameCustomer
john
Second select
nameSeller
bryan
What i want in one select
nameSeller
nameCustomer
bryan
john
Fil to the script to create table and bdd
-- Script de création de la base de données ENCHERES
-- type : SQL Server 2012
--
CREATE DATABASE BDDTEST2
GO
USE BDDTEST2
GO
CREATE TABLE CATEGORIES (
no_categorie INTEGER IDENTITY(1,1) NOT NULL,
libelle VARCHAR(30) NOT NULL
)
ALTER TABLE CATEGORIES ADD constraint categorie_pk PRIMARY KEY (no_categorie)
CREATE TABLE ENCHERES (
no_utilisateur INTEGER NOT NULL,
no_article INTEGER NOT NULL,
date_enchere datetime NOT NULL,
montant_enchere INTEGER NOT NULL
)
ALTER TABLE ENCHERES ADD constraint enchere_pk PRIMARY KEY (no_utilisateur, no_article)
CREATE TABLE RETRAITS (
no_article INTEGER NOT NULL,
rue VARCHAR(30) NOT NULL,
code_postal VARCHAR(15) NOT NULL,
ville VARCHAR(30) NOT NULL
)
ALTER TABLE RETRAITS ADD constraint retrait_pk PRIMARY KEY (no_article)
CREATE TABLE UTILISATEURS (
no_utilisateur INTEGER IDENTITY(1,1) NOT NULL,
pseudo VARCHAR(30) NOT NULL,
nom VARCHAR(30) NOT NULL,
prenom VARCHAR(30) NOT NULL,
email VARCHAR(20) NOT NULL,
telephone VARCHAR(15),
rue VARCHAR(30) NOT NULL,
code_postal VARCHAR(10) NOT NULL,
ville VARCHAR(30) NOT NULL,
mot_de_passe VARCHAR(30) NOT NULL,
credit INTEGER NOT NULL,
administrateur bit NOT NULL
)
ALTER TABLE UTILISATEURS ADD constraint utilisateur_pk PRIMARY KEY (no_utilisateur)
CREATE TABLE ARTICLES_VENDUS (
no_article INTEGER IDENTITY(1,1) NOT NULL,
nom_article VARCHAR(30) NOT NULL,
description VARCHAR(300) NOT NULL,
date_debut_encheres DATE NOT NULL,
date_fin_encheres DATE NOT NULL,
prix_initial INTEGER,
prix_vente INTEGER,
no_utilisateur INTEGER NOT NULL,
no_categorie INTEGER NOT NULL
)
ALTER TABLE ARTICLES_VENDUS ADD constraint articles_vendus_pk PRIMARY KEY (no_article)
ALTER TABLE ARTICLES_VENDUS
ADD CONSTRAINT encheres_utilisateur_fk FOREIGN KEY ( no_utilisateur )
REFERENCES UTILISATEURS ( no_utilisateur )
ON DELETE NO ACTION
ON UPDATE no action
ALTER TABLE ENCHERES
ADD CONSTRAINT encheres_articles_vendus_fk FOREIGN KEY ( no_article )
REFERENCES ARTICLES_VENDUS ( no_article )
ON DELETE NO ACTION
ON UPDATE no action
ALTER TABLE RETRAITS
ADD CONSTRAINT retraits_articles_vendus_fk FOREIGN KEY ( no_article )
REFERENCES ARTICLES_VENDUS ( no_article )
ON DELETE NO ACTION
ON UPDATE no action
ALTER TABLE ARTICLES_VENDUS
ADD CONSTRAINT articles_vendus_categories_fk FOREIGN KEY ( no_categorie )
REFERENCES CATEGORIES ( no_categorie )
ON DELETE NO ACTION
ON UPDATE no action
ALTER TABLE ARTICLES_VENDUS
ADD CONSTRAINT ventes_utilisateur_fk FOREIGN KEY ( no_utilisateur )
REFERENCES UTILISATEURS ( no_utilisateur )
ON DELETE NO ACTION
ON UPDATE no action
Link to insert value
USE BDDTEST2
GO
INSERT INTO [dbo].[UTILISATEURS]
([pseudo]
,[nom]
,[prenom]
,[email]
,[telephone]
,[rue]
,[code_postal]
,[ville]
,[mot_de_passe]
,[credit]
,[administrateur])
VALUES
('zorg'
,'john'
,'john'
,'j#k.c'
,'15454'
,'hjh'
,'hkk'
,'hjgjh'
,'hjkjg'
,0
,0 )
GO
INSERT INTO [dbo].[UTILISATEURS]
([pseudo]
,[nom]
,[prenom]
,[email]
,[telephone]
,[rue]
,[code_postal]
,[ville]
,[mot_de_passe]
,[credit]
,[administrateur])
VALUES
('zorg'
,'bryan'
,'bryan'
,'j#k.c'
,'15454'
,'hjh'
,'hkk'
,'hjgjh'
,'hjkjg'
,0
,0 )
GO
INSERT INTO [dbo].[CATEGORIES]
([libelle])
VALUES
('enfant')
GO
INSERT INTO [dbo].[ARTICLES_VENDUS]
([nom_article]
,[description]
,[date_debut_encheres]
,[date_fin_encheres]
,[prix_initial]
,[prix_vente]
,[no_utilisateur]
,[no_categorie])
VALUES
('Jouet',
'desc',
'2002-01-01',
'2003-01-01',
0,
0,
2,
1)
GO
INSERT INTO [dbo].[ENCHERES]
([no_utilisateur]
,[no_article]
,[date_enchere]
,[montant_enchere])
VALUES
(1,
1,
'2002-02-02',
50)
GO
Thanks
You can use a CROSS APPLY to pull back the buyer for each of the sellers. Consider the following:
SELECT u.nom AS nameSeller, x.nom nameBuyer
FROM ENCHERES e
INNER JOIN ARTICLES_VENDUS ac ON ac.no_article = e.no_article
INNER JOIN UTILISATEURS u ON u.no_utilisateur = ac.no_utilisateur
CROSS APPLY(
select u.nom
from UTILISATEURS u WHERE u.no_utilisateur = e.no_utilisateur
) X
lead will move the current row to 1 place above
Union will join data in single column
you need to have a common factor like date for order by clause
https://www.mssqltips.com/sqlservertutorial/9127/sql-server-window-functions-lead-and-lag/
with main_data as (
SELECT nom AS nameSeller,
'Seller' as category_seller_or_customer
FROM ENCHERES e
INNER JOIN ARTICLES_VENDUS ac ON ac.no_article = e.no_article
INNER JOIN UTILISATEURS u ON u.no_utilisateur = ac.no_utilisateur
WHERE nom_article LIKE '%ta%'
union
SELECT nom AS nameCustomer,
'Customer' as category_seller_or_customer
FROM ENCHERES e
INNER JOIN UTILISATEURS u ON e.no_utilisateur = u.no_utilisateur
WHERE e.no_utilisateur= 57
),
getting_seller_and_buyer AS (
select
*,
lead(category_seller_or_customer)
over(order by
[some date factor or something that both have in common]
) as current_seller_or_customer
from main_data
)
select
*,
case
when category = 'Seller' then current_seller_or_customer else end as seller,
case
when category = 'Customer' then current_seller_or_customer else end as customer
from
getting_seller_and_buyer

SQL Statement summarize missing employee certifications

I am trying to create a report on tables that I can't modify and am not sure if this is even possible.
Using the script below, I am trying to get a query result of:
--Certification | Employee | Has Certification
--CPR | Santa Clause | Yes
--CPR | Rudolph | No
CREATE TABLE [dbo].[Certification]([Id] [int] IDENTITY(1,1) NOT NULL,
[Name] [varchar](50) NOT NULL,
CONSTRAINT [PK_Certification] PRIMARY KEY CLUSTERED ([Id] ASC));
CREATE TABLE [dbo].[Employee]([Id] [int] IDENTITY(1,1) NOT NULL,
[Name] [varchar](50) NOT NULL,
CONSTRAINT [PK_Employee] PRIMARY KEY CLUSTERED ([Id] ASC));
CREATE TABLE [dbo].[EmployeeCertification]([Id] [int] IDENTITY(1,1) NOT NULL,
[CertificationID] [int] NOT NULL,
[EmployeeID] [int] NOT NULL,
CONSTRAINT [PK_EmployeeCertification] PRIMARY KEY CLUSTERED ([Id] ASC));
ALTER TABLE [dbo].[EmployeeCertification] WITH CHECK ADD CONSTRAINT
[FK_EmployeeCertification_Certification] FOREIGN KEY([CertificationID])
REFERENCES [dbo].[Certification] ([Id])
ALTER TABLE [dbo].[EmployeeCertification] CHECK CONSTRAINT
[FK_EmployeeCertification_Certification]
ALTER TABLE [dbo].[EmployeeCertification] WITH CHECK ADD CONSTRAINT
[FK_EmployeeCertification_Employee] FOREIGN KEY([EmployeeID])
REFERENCES [dbo].[Employee] ([Id])
ALTER TABLE [dbo].[EmployeeCertification] CHECK CONSTRAINT
[FK_EmployeeCertification_Employee]
INSERT INTO Certification (Name) VALUES ('CPR');
INSERT INTO Employee (Name) VALUES ('Santa Clause'),('Rudolph');
INSERT INTO EmployeeCertification (CertificationID,EmployeeID) VALUES(1,1);
You can cross join employees and certifications to generate all possible combinations, then use a subquery to check whether each tuple exists in the bridge table:
select c.name as certification, e.name as employee,
case when exists (
select 1
from employeecertification ec
where ec.employeeid = e.id and ec.certificationid = c.id
) then 'Yes' else 'No' end as has_certification
from employee e
cross join certification c
This can also be done with a left join:
select c.name as certification, e.name as employee,
case ec.id is null then 'No' else 'Yes' end as has_certification
from employee e
cross join certification c
left join employeecertification ec on ec.employeeid = e.id and ec.certificationid = c.id

SQL Query: I want to display UserName and role_discription using a junction table

Hi can someone please help?
I have three tables tblUsers, tblRoles and tblUserRoles
How do I display UserName from a tblUsers table and role_discription
from tblRoles table.
CREATE TABLE tblRoles(
roleID int IDENTITY(1,1) PRIMARY KEY NOT NULL,
role_description varchar(50) NOT NULL
);
)CREATE TABLE tblUsers(
userID int IDENTITY(1,1) PRIMARY KEY,
FirstName varchar(50) NOT NULL,
LastName varchar(50) NOT NULL,
Age int NOT NULL,
UserName varchar(50) NOT NULL,
Password varchar(50) NOT NULL);
create table tblUserRoles (
userID int REFERENCES tblUsers(userID) NOT NULL,
roleID int REFERENCES tblRoles(roleID)NOT NULL,
);
alter table tblUserRoles
Add Constraint PK_UserRoles
Primary Key Clustered (userID,roleID)
I know basic SELECT statements and can show everything in tblUserRoles table but would like to show names and descriptions instead of ID numbers
Here is a query to display user_name and role_description
SELECT t1.UserName , t2.role_description from tblUsers t1 INNER JOIN tblUserRoles t3 ON t1.userID = t3.userID INNER JOIN tblRoles t2 on t3.roleID = t2.roleID
Here the 1st join will join tables tblUsers and tblUserRoles on column userID and the 2nd join will join tables tblUserRoles and tblRoles on column roleID.

SQL Queries/Subqueries

I was wondering if someone could help me with this query? I am very stuck on this one:
"Show the sum of HoursWorked for each Type of OWNER but exclude services of employees who have ExperienceLevel of Junior and exclude any Type with less than three members."
CREATE TABLE OWNER
(
OwnerID Int NOT NULL IDENTITY (1,1) PRIMARY KEY,
OwnerName Char(30) NOT NULL,
OwnerEmail VarChar(100) NULL,
OwnerType Char(15) NOT NULL,
);
CREATE TABLE PROPERTY
(
PropertyID Int NOT NULL IDENTITY(1,1) PRIMARY KEY,
PropertyName Char(30) NOT NULL,
Street Char(20) NOT NULL,
City Char(25) NOT NULL,
State Char(10) NOT NULL,
Zip Char(5) NOT NULL,
OwnerID Int NOT NULL,
CONSTRAINT PROP_OWN_FK FOREIGN KEY(OwnerID)
REFERENCES OWNER(OwnerID),
);
CREATE TABLE GG_EMPLOYEE
(
EmployeeID Int NOT NULL IDENTITY(1,1) PRIMARY KEY,
LastName Char(35) NOT NULL,
FirstName Char(35) NOT NULL,
CellPhone Char(20) NOT NULL,
ExperienceLevel Char(25) NOT NULL,
);
CREATE TABLE SERVICE
(
PropertyID Int NOT NULL,
EmployeeID Int NOT NULL,
ServiceDate Char(15) NOT NULL,
HoursWorked Char(5) NOT NULL,
CONSTRAINT SERVICE_PK PRIMARY KEY(PropertyID, EmployeeID, ServiceDate),
CONSTRAINT SER_PRO_FK FOREIGN KEY(PropertyID)
REFERENCES PROPERTY(PropertyID),
CONSTRAINT SER_GG_EMP_FK FOREIGN KEY(EmployeeID)
REFERENCES GG_EMPLOYEE(EmployeeID),
);
SELECT o.OwnerType, SUM(Cast(HoursWorked as INT)) Sum_HrsWorked
FROM SERVICE s
INNER JOIN GG_EMPLOYEE e
ON s.EmployeeId = e.EmployeeId
INNER JOIN PROPERTY p
ON s.PropertyId = p.PropertyId
INNER JOIN OWNER o
ON o.OwnerID = p.OwnerID
WHERE e.ExperienceLevel <> 'JUNIOR'
Group By o.OwnerType
HAVING COUNT(OwnerType) > 3
Select Tbl1.OwnerName,Sum(TBl2.TTLHoursWorked) as TTLHoursWorked
From
(
Select TBl1.OwnerID,Tbl1.OwnerName,Tbl2.PropertyID,Tbl2.PropertyName
From Owner Tbl1
Inner Join
PROPERTY Tbl2
On Tbl1.OwnerID=Tbl2.OwnerID
)Tbl1
Inner Join
(
Select Tbl2.PropertyID,Cast(HoursWorked as numeric(5,4)) as TTLHoursWorked
From (Select * From GG_EMPLOYEE Where ExperienceLevel in(Select ExperienceLevel
From GG_EMPLOYEE
Where ExperienceLevel<>'Junior'
Group by ExperienceLevel Having Count(*)>3))as Tbl1
Inner Join SERVICE as Tbl2
On Tbl1.EmployeeID=Tbl2.EmployeeID
)Tbl2
On Tbl1.PropertyID=Tbl2.PropertyID
Group by Tbl1.OwnerName
SELECT o.OwnerType, SUM(CAST(s.HoursWorked as INT))
FROM
owner o
INNER JOIN property p
On o.ownerid = p.ownerid
INNER JOIN service s
ON p.propertyid = s.propertyid
INNER JOIN GG_employee e
On s.employeeid = e.employeeid
And e.experiencelevel <> 'junior'
GROUP BY
O.ownertype
HAVING
COUNT(DISTINCT o.ownerid) >= 3
Please forgive typos and capitalization as I'm on my phone.

Retrieve Data from Different Tables (SQL Server)

I have 4 tables in a SQL Server database with following schema:
Attendance
CREATE TABLE [dbo].[Attendance] (
[AttendanceId] UNIQUEIDENTIFIER DEFAULT (newid()) NOT NULL,
[CourseId] UNIQUEIDENTIFIER NOT NULL,
[StudentId] UNIQUEIDENTIFIER NOT NULL,
[SubjectId] UNIQUEIDENTIFIER NOT NULL,
[Semester] INT NOT NULL,
[Month] NVARCHAR (50) NOT NULL,
[Count] INT NOT NULL,
CONSTRAINT [PK_Attendance] PRIMARY KEY NONCLUSTERED ([AttendanceId] ASC),
CONSTRAINT [FK_Attendance_Student] FOREIGN KEY ([StudentId]) REFERENCES [dbo].[Student] ([StudentId]) );
Course
CREATE TABLE [dbo].[Course] (
[CourseId] UNIQUEIDENTIFIER DEFAULT (newid()) NOT NULL,
[Name] NVARCHAR (50) NOT NULL,
CONSTRAINT [PK_Course] PRIMARY KEY NONCLUSTERED ([CourseId] ASC)
);
Student
CREATE TABLE [dbo].[Student] (
[StudentId] UNIQUEIDENTIFIER DEFAULT (newid()) NOT NULL,
[CourseId] UNIQUEIDENTIFIER NOT NULL,
[Name] NVARCHAR (100) NOT NULL,
[RollNo] INT NOT NULL,
[Semester] INT NOT NULL,
CONSTRAINT [PK_Student] PRIMARY KEY NONCLUSTERED ([StudentId] ASC),
CONSTRAINT [FK_Student_Course] FOREIGN KEY ([CourseId]) REFERENCES [dbo].[Course] ([CourseId])
);
Subject
CREATE TABLE [dbo].[Subject] (
[SubjectId] UNIQUEIDENTIFIER DEFAULT (newid()) NOT NULL,
[CourseId] UNIQUEIDENTIFIER NOT NULL,
[Name] NVARCHAR (100) NOT NULL,
[Semester] INT NOT NULL,
CONSTRAINT [PK_Subject] PRIMARY KEY NONCLUSTERED ([SubjectId] ASC),
CONSTRAINT [FK_Subject_Course] FOREIGN KEY ([CourseId]) REFERENCES [dbo].[Course] ([CourseId])
);
I need to create a attendance report in the following format:
Course Name | Student Name | Subject Name | Semester | Month | Count
Please tell me what SQL Query I need to use and if there's any change in schema required then suggest the same.
I'm looking forward to have your replies.
Thanks,
You need to use a JOIN in your query so that it only returns rows which match a [StudentId] from the Attendance table.
e.g.
SELECT c.CourseName, s.StudentName, u.SubjectName, u.Semester, a.Month, a.Count
FROM Student s
JOIN Attendance a ON s.StudentId = a.StudentId
JOIN Course c ON a.CourseId = c.CourseId
JOIN Subject u ON c.CourseId = u.CourseId
Something along these lines will only return rows which specifically match