Show Empty Column on Sql Server Query

0md85ypi  于 2023-05-05  发布在  SQL Server
关注(0)|答案(2)|浏览(230)

I have three main Tables [Provider, Equipment and Services] and two relation tables one that relates provider with equipment and provider with services. These relational table is 1 to *

If I insert a provider that has equipment and services I can consult by using a normal query.

But if I insert only equipment but no services if I make the consult it only throws me the providers that has both services and provider.

SELECT 
    MAX(P.RazonSocial) AS 'Razon Social Proveedor', 
    STUFF((SELECT '; ' + S.TipoServicio 
           FROM Rel_ProvEquipo pE 
           INNER JOIN Servicio S ON pE.idEquipo = S.idServicio 
           WHERE pE.idProveedor = P.idProveedor
           FOR XML PATH ('')), 1, 1, '') [Servicios], 
    STUFF((SELECT '; ' + E.TipoEquipo 
           FROM Rel_ProvEquipo pE
           INNER JOIN Equipo E ON pE.idEquipo = E.idEquipo 
           WHERE pE.idProveedor = P.idProveedor
           FOR XML PATH ('')), 1, 1, '') [Equipos] 
FROM 
    Proveedor P
INNER JOIN 
    Rel_ProvServicio pServ ON P.idProveedor = pServ.idProveedor 
INNER JOIN 
    Rel_ProvEquipo pEquip ON P.idProveedor = pEquip.idProveedor 
GROUP BY 
    P.idProveedor 
ORDER BY 
    P.idProveedor

The query above is the one that I use to consult the information of the tables.

I want that in the results, if a provider doesn't have a services but it has equipment it shows the information with a column with no services (empty) as well if a provider doesn't have equipment but services it shows the services and a equipment column (empty)

Tables:

CREATE TABLE Proveedor 
(
    idProveedor int IDENTITY(1,1) NOT NULL,
    RazonSocial nvarchar (max) NOT NULL,

    CONSTRAINT PK_Proveedor PRIMARY KEY (idProveedor),
)

CREATE TABLE Servicio
(
    idServicio int IDENTITY(1,1) NOT NULL,
    TipoServicio nvarchar(35) NOT NULL,
    CONSTRAINT PK_Servicio PRIMARY KEY (idServicio)
)

CREATE TABLE Equipo
(
    idEquipo int IDENTITY(1,1) NOT NULL, 
    TipoEquipo nvarchar(35) NOT NULL
    CONSTRAINT PK_Equipo PRIMARY KEY (idEquipo)
)

CREATE TABLE Rel_ProvServicio
(
    idProveedor int NOT NULL,
    idServicio int NOT NULL, 
    CONSTRAINT FK_ProvServicio 
        FOREIGN KEY (idProveedor) REFERENCES Proveedor(idProveedor),
    CONSTRAINT FK_ServicioProv 
        FOREIGN KEY (idServicio) REFERENCES Servicio(idServicio) 
)

CREATE TABLE Rel_ProvEquipo
(
    idProveedor int NOT NULL,
    idEquipo int NOT NULL,
    CONSTRAINT FK_ProvEquipo 
        FOREIGN KEY (idProveedor) REFERENCES Proveedor(idProveedor),
    CONSTRAINT FK_EquipoProv 
        FOREIGN KEY (idEquipo) REFERENCES Equipo(idEquipo) 
)

Sample data:

--DATA PROVIDER
INSERT INTO PROVEEDOR (RazonSocial) VALUES ('Provider 1')
INSERT INTO PROVEEDOR (RazonSocial) VALUES ('Provider 2')
INSERT INTO PROVEEDOR (RazonSocial) VALUES ('Provider 3')

--DATA SERVICES
INSERT INTO SERVICIOS (TipoServicio) VALUES ('Service 1')
INSERT INTO SERVICIOS (TipoServicio) VALUES ('Service 2')
INSERT INTO SERVICIOS (TipoServicio) VALUES ('Service 3')

--DATA EQUIPMENT
INSERT INTO EQUIPOS (TipoEquipo) VALUES ('Equipment 1')
INSERT INTO EQUIPOS (TipoEquipo) VALUES ('Equipment 2')
INSERT INTO EQUIPOS (TipoEquipo) VALUES ('Equipment 3')

--DATA RELATION SERVICES PROVIDER 1 BOTH SERVICES AND EQUIPMENT

INSERT INTO Rel_ProvEquipo (idProveedor, idEquipo )VALUES (1,1)
INSERT INTO Rel_ProvEquipo (idProveedor, idEquipo )VALUES (1,2)
INSERT INTO Rel_ProvEquipo (idProveedor, idEquipo )VALUES (1,3)

INSERT INTO Rel_ProvServicio (idProveedor, idServicio)VALUES (1,1)
INSERT INTO Rel_ProvServicio(idProveedor, idServicio )VALUES (1,2)
INSERT INTO Rel_ProvServicio(idProveedor, idServicio)VALUES (1,3)

--DATA RELATION SERVICES EQUIPMENT PROVIDER 2 ONLY EQUIPMENT
INSERT INTO Rel_ProvEquipo (idProveedor, idEquipo )VALUES (2,1)
INSERT INTO Rel_ProvEquipo (idProveedor, idEquipo )VALUES (2,2)
INSERT INTO Rel_ProvEquipo (idProveedor, idEquipo )VALUES (2,3)

--DATA RELATION SERVICES EQUIPMENT PROVIDER 3 ONLY SERVICES
INSERT INTO Rel_ProvServicio (idProveedor, idServices)VALUES (3,1)
INSERT INTO Rel_ProvServicio (idProveedor, idServices )VALUES (3,2)
INSERT INTO Rel_ProvServicio (idProveedor, idServices)VALUES (3,3)

Screenshot of desired output:

qgelzfjb

qgelzfjb1#

You have a number of issues here:

  • The joins aren't necessary at all, as you are anyway joining inside the subqueries.

  • Left-joins are not the answer here, the join is not necessary in the first place.

  • You could use a left-join in the inner subquery, but that seems pointless as the results will be the same.

  • Therefore the outer GROUP BY is not necessary either.

  • The join in the first subquery should be Rel_ProvServicio not Rel_ProvEquipo

  • You can use STRING_AGG instead of FOR XML in newer versions of SQL Server

SELECT
  P.RazonSocial as [Razon Social Proveedor], 
  (
    SELECT STRING_AGG(S.TipoServicio, '; ')
    FROM Rel_ProvServicio ps
    INNER JOIN Servicio S ON ps.idServicio = S.idServicio 
    WHERE ps.idProveedor = P.idProveedor
  ) AS Servicios, 
  (
    SELECT STRING_AGG(E.TipoEquipo, '; ')
    FROM Rel_ProvEquipo pe
    INNER JOIN Equipo E ON pe.idEquipo = E.idEquipo 
    WHERE pe.idProveedor = P.idProveedor
  ) AS Equipos
FROM Proveedor P
ORDER BY P.idProveedor;

db<>fiddle

vsnjm48y

vsnjm48y2#

As @GMB says I make LEFT JOIN INSTEAD OF INNER

SELECT MAX(P.idProveedor),MAX(P.RazonSocial) as 'Razon Social Proveedor', 
STUFF((SELECT '; ' + S.TipoServicio FROM Rel_ProvServicio pS 
LEFT JOIN Servicio S ON pS.idServicio=S.idServicio 
WHERE pS.idProveedor=P.idProveedor
FOR XML PATH ('')), 1,1, '')[Servicios], 
STUFF((SELECT '; ' + E.TipoEquipo FROM Rel_ProvEquipo pE
LEFT JOIN Equipo E ON pE.idEquipo=E.idEquipo 
WHERE pE.idProveedor=P.idProveedor
FOR XML PATH ('')), 1,1, '')[Equipos] 
FROM Proveedor P
LEFT JOIN Rel_ProvServicio pServ ON P.idProveedor=pServ.idProveedor 
LEFT JOIN Rel_ProvEquipo  pEquip ON P.idProveedor=pEquip.idProveedor 
GROUP BY P.idProveedor ORDER BY P.idProveedor

相关问题