What I'm trying to do is to select all 4 of those tables with join but i can't figure it out how because there isn't a table connected to all of the others.
create table Encomenda(
idEncomenda int identity,
idFornededor int not null,
estado varchar not null,
Constraint pk_Encomenda Primary Key (idEncomenda),
);
create table Produto_Encomenda(
idProduto_Encomenda int identity,
idProduto int not null,
idEncomenda int not null,
quantidade int not null,
constraint pk_Produto_Encomenda Primary Key (idProduto_Encomenda),
constraint fk_Produto foreign key (idProduto) references Produto (idProduto) ,
constraint fk_idEncomenda foreign key (idEncomenda) references Encomenda (idEncomenda) ,
);
create table Fornecedor(
idFornecedor int identity,
nomeFornecedor varchar(60) not null,
moradaFornecedor varchar(60) not null,
contactoFornecedor int not null,
constraint pk_Fornecedor Primary Key (idFornecedor),
);
create table Produto(
idProduto int identity,
nomeProduto varchar(60) not null,
quantidadeExistenteProduto int not null,
precoUnidade float not null,
Constraint pk_produto Primary Key (idProduto),
);
I was trying to make a join between the 4 of them and what I would like to show/select are:
Fornecedor.nomeFornecedor, idEncomenda, Produto.nomeProduto and Produto_encomenda.quantidade" joined toguether where
Produto.idproduto = produto_Encomenda.idproduto
Fornecedor.idFornecedor = Encomenda.idFornecedor
I don't think I can explain better but in the end I wanted to select a table that containsFornecedor.nomeFornecedor, idEncomenda, Produto.nomeProduto and Produto_encomenda.quantidade, but because the 4 tables dont have 1 common table im lost in how to make the join :\ im probably just tired as hell but if someone could help me i would apreciatte cuz im so lost here
Ok, now that I think I better understand the question you need the following fields: Fornecedor.nomeFornecedor, idEncomenda, Produto.nomeProduto and Produto_encomenda.quantidade.
So, let's see if this works:
SELECT f.nomeFornecedor,
e.idEncomenda,
p.nomeProduto,
pe.quantidade
FROM Fornecedor as f
INNER JOIN Encomenda AS e
ON f.idFornecedor = e.idFornededor
INNER JOIN Produto_Encomenda as pe
ON e.idEncomenda = pe.idEncomenda
INNER JOIN Produto as p
ON p.idProduto = pe.idProduto
I think this should work
You join tables using the 'JOIN' statement. There are four types:
INNER - Only join where a match is found.
LEFT - Only join where a match is found in the right hand table, but join the whole of the left.
RIGHT - Only join where a match is found in the left hand table, but join the whole of the right.
FULL OUTER - Join both tables together, even where no match is found.
A basic JOIN goes like this:
INNER JOIN MyTable ON MyTable.ID = SomeTable.ID
You should read this.
Hope it helps!
Related
I have three tables DEPARTMENTS, SEMESTER and SUBJECTS
CREATE TABLE DEPARTMENTS
(
D_ID INT PRIMARY KEY identity(1, 1),
department_name VARCHAR(50) NOT NULL
);
CREATE TABLE SEMESTER
(
D_ID INT FOREIGN KEY REFERENCES departments(D_ID),
sem_id INT PRIMARY KEY identity(1, 1),
semester INT CHECK
(semester BETWEEN 1 AND 8) NOT NULL
);
CREATE TABLE SUBJECTS
(
D_ID INT FOREIGN KEY REFERENCES departments(D_ID),
sem_id INT FOREIGN KEY REFERENCES semester(sem_id),
sub_id INT PRIMARY KEY identity(1, 1),
sub_name VARCHAR(50),
syllabus VARBINARY(MAX),
exam_format VARBINARY(MAX)
);
If user insert department_name in DEPARTMENTS table and semester from semester table then how to get sub_name from subject
Firstly, your design is wrong. you don't need to have a reference from Subject to Departments because Department is accessible through Semester and the D_Id in Subject is redundant, IMHO.
Second, what is your criteria for retrieving subject?
Select Sub_Name
from Subjects as sbj
inner join Departments as dpt on sbj.D_Id = dpt.D_Id
inner join Semester as smt on sbj.sem_id = smt.sem_id
where (YOUR CRITERIA)
This is basically the general correlation among your tables,
so you could specify the conditions and list of fields to be retrieved.
However it's best to rectify your design first and then access department
through Semester :
inner join Departments as dpt on smt.D_Id = dpt.D_Id
thereby you're gonna use the dependency in semester rather than subjects!
p.s.
if the department in subject is different from the on in semester
then your layout is good as it is, but if they're same thing then
you can get rid of the latter
You need to use join here
select sub.sub_name,dep.department_name,sem.semester
from subjects sub
join departments dep on dep.d_id = sub.d_id
join semester sem on sem.sem_id = sub.sem_id;
I have these 3 tables: Register, Brand and Clothing, where Register saves int numbers from a Brand dropdownlist and a Clothing dropdownlist, but in the select I dont want the int value, but the value who the respective tables represents. (IdBrand 1 = Nike, IdBrand 2 = Adidas). It is "working" but I dont know if I am doing something wrong, cause when I try the code on Sql Server "new query" I have 9 lines resulting even I having JUST ONE REGISTER on the RegisterTable, it is more a "logic" question, is it normal to have a lots of rows on the "select display"?
The Code
select Register.*, Clothing.ClothingName, Brand.BrandName
from Register
inner join Clothing
on RegisterClothingId1 = ClothingId
or RegisterClothingId2 = ClothingId
or RegisterClothingId3 = ClothingId
inner join Brand
on RegisterBrandId1 = BrandId
or RegisterBrandId2 = BrandId
or RegisterBrandId3 = BrandId
I also try with "and" instead "or" but it affects/returns zero lines.
Again, this code "is working". I just do not know if it is normal to have so many lines resulting with JUST ONE register. Because if 1 register gives 9 lines I wonder 100 register will give 900 lines for example.
Thank you.
The table have only 3 Brand columns and 3 Clothing columns that inherats from the other 2 tables
Register Table
CREATE TABLE [dbo].[Register] (
[RegisterId] INT IDENTITY (1, 1) NOT NULL,
[RegisterPersonId] INT NOT NULL,
[RegisterPersonNote] NCHAR (60) NULL,
[RegisterCareerId] INT NOT NULL,
[RegisterEvent] NCHAR (60) NOT NULL,
[RegisterEventYear] INT NOT NULL,
[RegisterImgDressed] VARBINARY (MAX) NOT NULL,
[RegisterClothingId1] INT NOT NULL,
[RegisterBrandId1] INT NOT NULL,
[RegisterClothingName1] NCHAR (60) NOT NULL,
[RegisterClothingImg1] VARBINARY (MAX) NOT NULL,
[RegisterClothingId2] INT NOT NULL,
[RegisterBrandId2] INT NOT NULL,
[RegisterClothingName2] NCHAR (60) NOT NULL,
[RegisterClothingImg2] VARBINARY (MAX) NOT NULL,
[RegisterClothingId3] INT NOT NULL,
[RegisterBrandId3] INT NOT NULL,
[RegisterClothingName3] NCHAR (60) NOT NULL,
[RegisterClothingImg3] VARBINARY (MAX) NOT NULL,
[RegisterYoutube] NCHAR (500) NOT NULL,
[RegisterExternalLink] NCHAR (500) NULL,
[RegisterNote] NCHAR (60) NULL,
[RegisterNote2] NCHAR (60) NULL,
CONSTRAINT [PK_Register] PRIMARY KEY CLUSTERED ([RegisterId] ASC),
CONSTRAINT [FK_Register_Brand1] FOREIGN KEY ([RegisterBrandId1]) REFERENCES [dbo].[Brand] ([BrandId]),
CONSTRAINT [FK_Register_Brand2] FOREIGN KEY ([RegisterBrandId2]) REFERENCES [dbo].[Brand] ([BrandId]),
CONSTRAINT [FK_Register_Brand3] FOREIGN KEY ([RegisterBrandId3]) REFERENCES [dbo].[Brand] ([BrandId]),
CONSTRAINT [FK_Register_Clothing1] FOREIGN KEY ([RegisterClothingId1]) REFERENCES [dbo].[Clothing] ([ClothingId]),
CONSTRAINT [FK_Register_Clothing2] FOREIGN KEY ([RegisterClothingId2]) REFERENCES [dbo].[Clothing] ([ClothingId]),
CONSTRAINT [FK_Register_Clothing3] FOREIGN KEY ([RegisterClothingId3]) REFERENCES [dbo].[Clothing] ([ClothingId])
);
Other two are simple tables, have only BrandId and BrandName, and Clothing Id and ClothingName
I think your Register table needs redesign. Columns with name[RegisterClothingNameX] and [RegisterClothingImgX] should be on the Clothing table unless they are not describing a particular clothing item. Below query should give you the data you require
select
Register.*,
c1.ClothingName AS Clothing1Name,
c2.ClothingName AS Clothing2Name,
c3.ClothingName AS Clothing3Name,
b1.BrandName AS Brand1Name,
b2.BrandName AS Brand2Name,
b3.BrandName AS Brand3Name
from
Register
INNER JOIN Clothing c1 ON RegisterClothingId1 = c1.ClothingId
INNER JOIN Clothing c2 ON RegisterClothingId2 = c2.ClothingId
INNER JOIN Clothing c3 ON RegisterClothingId3 = c3.ClothingId
INNER JOIN Brand b1 ON RegisterBrandId1 = b1.BrandId
INNER JOIN Brand b2 ON RegisterBrandId2 = b2.BrandId
INNER JOIN Brand b3 ON RegisterBrandId3 = b3.BrandId
Your first join will produce 3 rows and all this 3 rows have 3 brand ids (3 rows x 3 Brands/Cols - so the second join will produce 9 records). And this may change as per the values stored in the RegisterClothingId1, RegisterBrandId3
I have an old view that takes 4 mins to run, I have been asked to speed it up. The FROM looks like this:
FROM TableA
CROSS JOIN ViewA
INNER JOIN TableB on ViewA.Name = TableB.Name
AND TableA.Code = TableB.Code
AND TableA.Location = TableB.Location
WHERE (DATEDIFF(m, ViewA.SubmitDate, GETDATE()) = 1) -- Only pull last months rows
Table A has around 99k rows, ViewA has around 2000 rows and TableB has around 101K rows. I think the problem is at the INNER JOIN because it I remove it, the query takes 1 second.
My first thought was to see if I could down the number of rows in ViewA by breaking the whole thing into CTEs but this made zero impact. I am thinking I need to index TableB, because it is just a bunch of varchars being used in the joins. I am now changing it to temp tables so I can index it. I can not change the underlying tables and views. Is index temp tables a good way to go, or is there a better solution.
Edit to add info regarding existing indexes. Only thing with an index on it right now is TableA.Id which is the PK and a clustered Index. TableB has an Id field but it is not the PK. ViewA is not indexed.
Edit again to correct some structure. SubmitDate is in the View, not the table.
Here is a very basic structure:
CREATE TABLE TableA
(
Id int NOT NULL PRIMARY KEY,
Section varchar(20) NULL,
Code varchar(20) NULL
)
CREATE TABLE TableB
(
Id int NOT NULL PRIMARY KEY,
Name varchar(20) NULL,
Code varchar(20) NULL,
Section varchar(20) NULL
)
CREATE TABLE TableC
(
Id int NOT NULL PRIMARY KEY,
Name varchar(20) NULL,
SubmitDate DateTime NOT NULL
)
CREATE TABLE TableD
(
Id int NOT NULL PRIMARY KEY,
Section varchar(20) NULL
)
CREATE VIEW ViewA
AS
SELECT c.Section, d.Name, c.SubmitDate
FROM TableC c
JOIN TableD d ON a.Id = b.Id
One improovement is to rewrite where clause into sargable clause. Add index to SubmitDate if there is no index and change query to:
FROM TableA
CROSS JOIN ViewA
INNER JOIN TableB on ViewA.Name = TableB.Name
AND TableA.Code = TableB.Code
AND TableA.Location = TableB.Location
WHERE
TableA.SubmitDate >=DATEADD(MONTH,DATEDIFF(MONTH,0,GETDATE())-1,0)
And TableA.SubmitDate < Dateadd(DAY, 1, DATEADD(MONTH,
DATEDIFF(MONTH, -1, GETDATE())-1, -1) )
Also add nonclustered indexes on Name, Code and Location columns.
I have a question about left join performance.
Supose I have this 2 tables:
CREATE TABLE "Jobs" (
"Id" INT NOT NULL,
"Department" VARCHAR(25) NULL,
"Job" VARCHAR(50) NOT NULL,
PRIMARY KEY ("Id", "JobName")
);
CREATE TABLE "Workers" (
"Id" INT NOT NULL,
"JobID" INT NOT NULL,
"WorkerName" VARCHAR(25) NULL,
"WorkerSurname" VARCHAR(25) NULL,
"JobName" VARCHAR(50) NOT NULL,
PRIMARY KEY ("Id")
);
Now, I want to left join both tables in order to get all the jobs on an specific department for an specific worker, even if the worker does´t take that job.
select t1.job, t1.department, t2.WorkerName, t2.WorkerSurname
from (SELECT distinct job, department FROM Jobs WHERE DEpartment= #depto) t1
left join dbo.Workers t2 on t1.id=t2.Jobid and t2.WorkerName=#NAME
This sql tooks about 0,171ms.
But, if I join with "Job" instead of "id":
select t1.job, t1.department, t2.WorkerName, t2.WorkerSurname
from (SELECT distinct job, department FROM Jobs WHERE DEpartment= #depto) t1
left join dbo.Workers t2 on t1.Job=t2.JobName and t2.WorkerName=#NAME
I tooks about 0,030 ms.
Can anyone explain me why is this happening? i thought integer joins were faster than varchar ones
Thanks
I created the following tables and inserted few values.
create table books
(
bookid integer primary key,
booktitle varchar(20),
year integer,
publisherid integer foreign key references publisher(publisherid),
price integer,
number integer
)
create table publisher
(
publisherid integer primary key,
publishername varchar(20)
)
create table author
(
authorid integer primary key,
authorname varchar(20)
)
create table bookauthor
(
bookid integer foreign key references books(bookid),
authorid integer references author(authorid),
earnings integer
)
create table bookreference
(
bookid integer foreign key references books(bookid),
referencebook varchar(20),
times integer
)
create table reviewer
(
reviewerid integer primary key,
reviewername varchar(20)
)
create table bookreview
(
bookid integer foreign key references books(bookid),
reviewerid integer foreign key references reviewer(reviewerid),
score integer
)
Now, I want to solve following query in SQL Server 2000. Find all the books published in 2003 and reviewed by both ‘Sammer Tulpule’ and ‘Hemant Mahta’ . I am not getting any idea about query. How can I write it?
Thanks,
Pooja
SELECT b.bookid as bookid
FROM (books b INNER JOIN bookreview br ON (br.bookid=b.bookid))
INNER JOIN reviewer r ON (br.reviewerid = r.reviewerid)
WHERE year=2003 AND r.reviewername IN ('Sammer Tulpule', 'Hemant Mahta')
GROUP BY b.bookid
HAVING COUNT(r.reviewerid) >= 2
Obviously, this is assuming that you don't have duplicated entries in the bookreview table.
(SELECT b.* FROM books b, bookreview br, reviewer rv WHERE b.year = 2003 AND br.bookid = b.bookid and br.reviewerid = rv.reviewerid and rv.reviewername = 'Sammer Tulpule')
INTERSECT
(SELECT b.* FROM books b, bookreview br, reviewer rv WHERE b.year = 2003 AND br.bookid = b.bookid and br.reviewerid = rv.reviewerid and rv.reviewername = 'Hemant Mahta')
I am typing this on the fly so there might be small errors, but you get the general idea...