How to join in sql with multiple tables (need) join multiple references? - sql

Some table only have identity columns but this is because this is a example only.
create table producto(
idproducto int identity primary key
)
create table inventario(
idInventario id int identity primary key,
idproducto int,
foreign key (idproducto) references producto(idproducto)
)
create table sucursal(
idSucursal id int identity primary key
)
create table inventariosucursal(
idinventariosucursal id int primary key,
idsucursal int,
idinventario int,
foreign key (idsucursal) references sucursal (idsucursal),
foreign key (idinventario) references inventario (idinventario),
)
create table mejoresventasxsucursal
(
mejoresventasxsucursal id int primary key,
idsucursal int,
idproducto int,
foreign key (idsucursal) references sucursal(idsucursal),
foreign key (idproducto) references producto (idproducto)
)
What do I need?
select the stocking ( inventario table ) by every branch office (sucursal table) but only most selled products (mejoresventasxsucursal table).
the problem is mejoresventasxsucursal table does "join" with 2 tables product and sucursal but after i have other table with does "join" with same 2 tables product and sucursal.
select s.id,i.id,p.id,
from producto p
join inventario i on p.idproducto = i.idproducto
join inventariosucursal i_s on i_s.idinventario = i.idinventario
join sucursal s on i_s on i_s.idsucursal = s.idsucursal
join producto p on i.producto = p.idproducto
join mejoresventasxsucursal mv on mv.idsucursal = s.idsucursal
Here is the problem. I need join mejoresventasxsucursal with producto. I know I could do something as join producto p2 but I would like to know what is the best way for join with producto. I know other solution is in where condition doing where p.idproducto=mv.idprocucto

Related

create breadcrumb from sql closure table and calculate depth

I have created a simple hierarchy with closure table and I want to create breadcrumb dynamically and also to calculate the depth.
The code for the structure is:
CREATE TABLE categories (
id int IDENTITY(1,1) not null,
created_date datetime not null DEFAULT GETDATE(),
updated_date datetime not null DEFAULT GETDATE(),
title nvarchar(max) NOT NULL,
CONSTRAINT PK_categories_id PRIMARY KEY CLUSTERED (id),
);
CREATE TABLE childcategories (
parent_id int,
child_id int,
CONSTRAINT PK_childcategories PRIMARY KEY NONCLUSTERED ([parent_id],[child_id]),
CONSTRAINT FK_childcategories_parent_id FOREIGN KEY (parent_id) REFERENCES
categories(id),
CONSTRAINT FK_childcategories_child_id FOREIGN KEY (child_id) REFERENCES
categories(id),
);
insert into categories(title)
values ('hardware'), ('cpu'), ('gpu') , ('intel'), ('amd'), ('nvidia')
insert into childcategories(parent_id,child_id)
values (1,2), (1,3),(2,4), (2,5),(3,4), (3,5), (3,6)
So far the recursive cte I have is:
with cpe as (
select c.id as parent_id,c.title as parent_title,children.id as
child_id,children.title as child_title
from categories c
inner join childcategories parents on parents.parent_id=c.id
inner join categories children on children.id=parents.child_id
union all
select children.id as parent_id,children.title as parent_title,children.id as
child_id,children.title as child_title
from cpe
inner join childcategories cteparents on cteparents.child_id=cpe.parent_id
inner join categories children on children.id=cteparents.parent_id
)
select * from cpe;

Joining multiple tables + HAVING clause

I have 4 tables :
create table Hotel (
numHotel int primary key,
nomHotel varchar(30),
ville varchar(30),
etoiles tinyint
);
create table Chambre (
numChambre int identity primary key,
numHotel int foreign key references Hotel(numHotel),
etage tinyint,
prixnuit smallmoney not null check (prixnuit>=100)
);
create table Client (
cinClient varchar(10) primary key,
nom varchar(30),
prenom varchar(30),
adresse varchar(255) default 'non renseignée',
telephone varchar(10) check (telephone like '0%' and len(telephone)=10)
);
create table reservation (
numReservation int identity primary key,
numChambre int foreign key references Chambre(numChambre),
numCl varchar(10) foreign key references Client(cinClient),
dateArrivee date,
dateDepart date,
constraint ck_dates check ((Datediff(day,dateArrivee,dateDepart)>0))
);
Column names are French, but I think they're understandable.
So the question is : I need to select the names of Hotels (nomHotel) having achieved a total price higher than a certain price (e.g. 10000)
This is what I did on paper :
select nomHotel from Hotel h join Chambre ch on h.numHotel=ch.numChambre join reservation r on ch.numChambre=r.numChambre
group by nomHotel
having COUNT(r.numChambre)*ch.prixnuit>10000
And (of course) I got it wrong.
Any Help is appreciated, Thanks.
translations : "prixnuit" is the room's (chambre) price per night.
The total revenue (I think) is based on the number of reservations.
I'm thinking you need to calculate the number of nights per reservation, no?
So, maybe:
select nomHotel,
sum(Datediff(day,r.dateArrivee,r.dateDepart)*ch.prixnuit)
from Hotel h join Chambre ch on h.numHotel=ch.numChambre join reservation r
on ch.numChambre=r.numChambre
group by nomHotel
having sum(Datediff(day,r.dateArrivee,r.dateDepart)*ch.prixnuit)>10000
select nomHotel, sum(Datediff(day,dateArrivee,dateDepart) * prixnuit)
from Hotel h join Chambre ch on h.numHotel=ch.numHotel
join reservation r on ch.numChambre=r.numChambre
group by nomHotel
having sum(Datediff(day,dateArrivee,dateDepart) * prixnuit)>1000

SQL double primary key, many-to-many relationship

I'd like to connect 3 tables. In one of them I must use a compound primary key. I know, how to deal with single. I have the following tables to connect:
CREATE TABLE Med_list
(
ID_med_list INT IDENTITY(200001,1) ,
No_med_list INT,
ID_med INT REFERENCES Med(ID_med),
PRIMARY KEY(ID_med_list, No_med_list)
)
CREATE TABLE Med
(
ID_med INT IDENTITY(3001,1) PRIMARY KEY ,
Name VARCHAR(20)
)
CREATE TABLE Visit
(
ID_Visit INT IDENTITY(600001,1) PRIMARY KEY,
ID_patient INT REFERENCES Patients(ID_patient),
Visit_date Datetime,
ID_med_duty INT,
No_med_list INT
)
I would like to every patient could have more than one medicine during one visit. I don't know how to connect table Visit and Med_list the way acceptable to SQL Server.
Thank you in advance for every hint or help:)
You need a many to many relation, if Med_list is supposed to be this relation (medicine to visits) then you are only missing one foreign key that points to the visit so the tables relation looks like this
Patient. <--- Visit. <--- Med_list. ---> Meds
The tables like this:
CREATE TABLE Med_list
(
ID_med_list INT IDENTITY(200001,1) ,
No_med_list INT,
ID_med INT REFERENCES Med(ID_med),
ID_Visit INT REFERENCES Visit(ID_Visit)
PRIMARY KEY(ID_med_list, No_med_list)
)
CREATE TABLE Med
(
ID_med INT IDENTITY(3001,1) PRIMARY KEY ,
Name VARCHAR(20)
)
CREATE TABLE Visit
(
ID_Visit INT IDENTITY(600001,1) PRIMARY KEY,
ID_patient INT REFERENCES Patients(ID_patient),
Visit_date Datetime,
ID_med_duty INT,
No_med_list INT
)
And your query can look like this
Select * From patients p
Join Visit v on v.ID_Patient = p.ID_Patient
Join Med_list ml on ml.ID_Visit = v.ID_Visit
Join Med m on m.ID_med = ml.ID_med
You could try this
I am also new in many-to-many relationship query.
SQLFiddle Example
SELECT
P.name,
M.Name
FROM
med_list ML
LEFT JOIN med M ON m.ID_med=ML.ID_med
LEFT JOIN visit V ON V.ID_Visit=ML.ID_Visit
LEFT JOIN patients P ON P.ID_patient=V.ID_patient

INSERT Conflict on Virtual Table SQL

I am having a problem on the INSERT because of a FK reference. The process goes like this:
I create the table Cuentas, and Cuentas_Con_RowNumber
I select from a huge table with over 3 million records. Because some are repeated and I need to store only 1 "cuenta", I made the tempDB. I have to do this, because on the huge db there are many records with the same Cuenta_Nro with different transactions, and I just need one.
I select from the tempDB all the columns but the RowNumber and then insert it into the Cuentas table.
The problem is that the tempDB Pais (country) column is not a FK which references to the Paises (countries) table, and on the original table (Cuentas) it does, therefore, it crashes.
Code:
CREATE TABLE Paises
(
Pais_Id numeric(18,0) PRIMARY KEY NOT NULL,
Pais_Nombre varchar(255) NOT NULL
)
CREATE TABLE Cuentas
(
Cuenta_Nro numeric(18,0) PRIMARY KEY NOT NULL,
Cuenta_Estado varchar(255),
Cuenta_Moneda varchar(255) DEFAULT 'Dolar',
Cuenta_Tipo numeric(18,0)
FOREIGN KEY REFERENCES Tipo_De_Cuentas(Tipo_De_Cuenta_Id),
Cuenta_PaisOrigen numeric(18, 0)
FOREIGN KEY REFERENCES Paises(Pais_Id),
Cuenta_PaisAsignado numeric(18, 0)
FOREIGN KEY REFERENCES Paises(Pais_Id),
Cuenta_Fec_Cre datetime,
Cuenta_Fec_Cierre datetime,
Cuenta_Tarjeta numeric(18, 0)
FOREIGN KEY REFERENCES Tarjetas(Tarjeta_Nro),
Cuenta_Cliente numeric(18, 0)
FOREIGN KEY REFERENCES Clientes(Cliente_Id)
)
CREATE TABLE #Cuentas_Con_RowNumer
(
Cuenta_Nro numeric(18,0) PRIMARY KEY NOT NULL,
Cuenta_Estado varchar(255),
Cuenta_PaisOrigen numeric(18,0)),
Cuenta_Fec_Cre datetime,
Cuenta_Fec_Cierre datetime,
Cuenta_Cliente numeric(18,0),
Cuenta_Tarjeta numeric(18,0),
RowNumber int
)
INSERT INTO #Cuentas_Con_RowNumer
SELECT *
FROM (SELECT
Maestro.Cuenta_Numero, Maestro.Cuenta_Estado, Maestro.Cuenta_Pais_Codigo,
Maestro.Cuenta_Fecha_Creacion, Maestro.Cuenta_Fecha_Cierre, Clientes.Cliente_Id, Maestro.Tarjeta_Numero,
ROW_NUMBER() OVER (PARTITION BY Maestro.Cuenta_Numero ORDER BY Maestro.Cuenta_Numero) AS RowNumber
FROM gd_esquema.Maestra Maestro, dbo.Clientes
WHERE
Clientes.Cliente_Apellido = Maestro.Cli_Apellido AND
Clientes.Cliente_Nombre = Maestro.Cli_Nombre) AS a
WHERE a.RowNumber = '1'
INSERT INTO Cuentas
(
Cuenta_Nro, Cuenta_Estado, Cuenta_PaisOrigen, Cuenta_Fec_Cre,
Cuenta_Fec_Cierre, Cuenta_Cliente, Cuenta_Tarjeta
)
SELECT
Cuenta_Nro, Cuenta_Estado, Cuenta_PaisOrigen, Cuenta_Fec_Cre,
Cuenta_Fec_Cierre, Cuenta_Cliente, Cuenta_Tarjeta
FROM #Cuentas_Con_RowNumer
The error message is:
Instrucción INSERT en conflicto con la restricción FOREIGN KEY "FK__Cuentas__Cuenta___24B338F0". El conflicto ha aparecido en la base de datos "GD1C2015", tabla "dbo.Paises", column 'Pais_Id'.
The issue is because Maestro.Cuenta_Pais_Codigo column is being pulled from gd_esquema.Maestra table which in turn is going as Cuenta_PaisOrigen in target table and has a foreign key defined.
There will be some records which are being selected for insert Cuentas table that doesn't have a matching Pais_Id record in dbo.Paises table.
You can add a inner join as below and check the results as :
INSERT INTO #Cuentas_Con_RowNumer
SELECT *
FROM (SELECT
...
FROM gd_esquema.Maestra Maestro
inner join dbo.Clientes on
Clientes.Cliente_Apellido = Maestro.Cli_Apellido AND
Clientes.Cliente_Nombre = Maestro.Cli_Nombre
inner join Paises P on Maestro.Cuenta_Pais_Codigo = P.Pais_Id
) AS a
WHERE a.RowNumber = '1'

Business-Logic Relationships in SQL

Can anyone please tell me how can one estabilish 1 to 0..1 and 1 to 1..* relationships between tables in SQL (Server)?
Thank you very much.
1 to 1..*
Create a Foreign key from a parent table to the primary key of the child (lookup table).
CREATE TABLE A
(
id int NOT NULL IDENTITY(1,1) PRIMARY KEY,
Somecolumn int,
SomeOtherColumn Varchar(50),
B_id int CONSTRAINT FOREIGN KEY REFERENCES B(id),
-- ...other columns
)
CREATE TABLE B
(
id int NOT NULL IDENTITY(1,1) PRIMARY KEY,
Name Varchar(50)
)
1 to 0..1
Create a table with the primary key also defined as a Foreign key to the parent table
CREATE TABLE [Master]
(
id int NOT NULL IDENTITY(1,1) PRIMARY KEY,
Somecolumn int,
SomeOtherColumn Varchar(50),
-- ...other columns
)
CREATE TABLE [Child]
(
id int NOT NULL PRIMARY KEY,
OtherColumn Varchar(50),
)
ALTER TABLE Child
ADD CONSTRAINT FK_Master FOREIGN KEY (id) REFERENCES Master(id)
One to many
Define two tables (example A and B), with their own primary key
Define a column in Table A as having a Foreign key relationship based on the primary key of Table B
This means that Table A can have one or more records relating to a single record in Table B.
If you already have the tables in place, use the ALTER TABLE statement to create the foreign key constraint:
ALTER TABLE A ADD CONSTRAINT FOREIGN KEY fk_b ( b_id ) references b(id)
* fk_b: Name of the foreign key constraint, must be unique to the database
* b_id: Name of column in Table A you are creating the foreign key relationship on
* b: Name of table, in this case b
* id: Name of column in Table B