T-SQL, Zeigen Sie eine Reihe von Zeilen (spezifische Spalte) als Feld für einen besseren Desc an, bitte siehe die Tabellenbeziehung

dba.stackexchange https://dba.stackexchange.com/questions/12131

Frage

Ich habe schon seit einiger Zeit ein Problem, dass ich mit einem Beispiel von 5 Tischen zeigen kann (ich habe es tatsächlich mit mehr als 5!):

--------------------------------
shipments                       |
--------------------------------
idShipment | idRoute | idClient |
1          | 1       |     1    |
2          | 2       |     1    |
3          | 2       |     2    |
---------------------------------

-----------------------------------------
routes                                   |
-----------------------------------------
idRoute    | shortNameRoute |    name    |
1          | ACA            |  ACAPULCO  |
2          | MTY            |  MONTERREY |
-----------------------------------------

-------------------------
points                   |
-------------------------
idPoint    | PointName   |
1          | ACAPULCO    |
2          | ACAPULCO_2  |
3          | MONTERREY   |   
4          | MONTERREY_2 | 
--------------------------

-------------------------
clients                  |
-------------------------
idClient   | ClientName  |
1          | Mocosoft    |
2          | Mapple      |
--------------------------



 /*This table has the relationship between routes and points*/
--------------------------------
routePoints                     |
--------------------------------
idRoutePoint | idRoute | idPoint|
1            |   1     |   1    |
2            |   1     |   2    |
3            |   2     |   3    |
4            |   2     |   4    |
--------------------------------

Wie kann ich den "Punktnamen) für eine Route als Feld in einem Ergebnissatz erhalten? Zum Beispiel:

----------------------------------------------------------------
result                                                          |
----------------------------------------------------------------
idShipment | shortNameRoute | points                 | client   |
1          | ACA            | ACAPULCO,ACAPULCO_2    | Mocosoft |
2          | MTY            | MONTERREY,MONTERREY_2  | Mapple   |
-----------------------------------------------------------

Bisher habe ich .NET -Code verwendet, um die Punkte nach Route zu verarbeiten. Ich stelle mir vor, es gibt eine effizientere Möglichkeit, dies mit T-SQL zu tun.

Vielleicht muss ich meine Datenbank effizienter "normalisieren"?

Ich mag es nicht, eine Anfrage für jede Sendung zusammen mit zusätzlichen Schleifen in meinem Code durchzuführen, aber bis jetzt ist es der einzige Weg und ich bin irgendwie verloren.

Ich gehe davon aus, dass die Lösung so etwas wie Pivot, Wählen Sie verschachtelt oder wahrscheinlich "mit" gemeinsamen Tabellenausdrücken aus, aber ich bin mir nicht sicher.

Hinweis: Ich verwende SQLServer 2008 R2

Hier ist das Skript zum Erstellen des DB mit Datenbeispiel (test_routes)

USE [TEST_ROUTES]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[shipments]
(
    [idShipment] [int] IDENTITY(1,1) NOT NULL,
    [idRoute] [int] NOT NULL,
    [idClient] [int] NOT NULL,
    CONSTRAINT [PK_shipments] PRIMARY KEY CLUSTERED 
    (
        [idShipment] ASC
    ) WITH (
        PAD_INDEX  = OFF
        , STATISTICS_NORECOMPUTE  = OFF
        , IGNORE_DUP_KEY = OFF
        , ALLOW_ROW_LOCKS  = ON
        , ALLOW_PAGE_LOCKS  = ON
        ) ON [PRIMARY]
) ON [PRIMARY];

GO

SET IDENTITY_INSERT [dbo].[shipments] ON;

INSERT [dbo].[shipments] ([idShipment], [idRoute], [idClient]) VALUES (1, 1, 1);
INSERT [dbo].[shipments] ([idShipment], [idRoute], [idClient]) VALUES (2, 2, 1);
INSERT [dbo].[shipments] ([idShipment], [idRoute], [idClient]) VALUES (3, 2, 2);

SET IDENTITY_INSERT [dbo].[shipments] OFF;


SET ANSI_NULLS ON;
GO
SET QUOTED_IDENTIFIER ON;
GO

CREATE TABLE [dbo].[routes]
(
    [idRoute] [int] NOT NULL,
    [shortNameRoute] [nvarchar](50) NOT NULL,
    [routeName] [nvarchar](50) NOT NULL,
    CONSTRAINT [PK_routes] PRIMARY KEY CLUSTERED 
    (
        [idRoute] ASC
    ) WITH (
        PAD_INDEX  = OFF
        , STATISTICS_NORECOMPUTE  = OFF
        , IGNORE_DUP_KEY = OFF
        , ALLOW_ROW_LOCKS  = ON
        , ALLOW_PAGE_LOCKS  = ON
    ) ON [PRIMARY]
) ON [PRIMARY];

GO
INSERT [dbo].[routes] ([idRoute], [shortNameRoute], [routeName]) VALUES (1, N'ACA', N'ACAPULCO');
INSERT [dbo].[routes] ([idRoute], [shortNameRoute], [routeName]) VALUES (2, N'MTY', N'MONTERREY');

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[routePoints]
(
    [idRoutePoints] [int] NOT NULL,
    [idRoute] [int] NOT NULL,
    [idPoint] [int] NOT NULL,
    CONSTRAINT [PK_routePoints] PRIMARY KEY CLUSTERED 
    (
        [idRoutePoints] ASC
    ) WITH (
        PAD_INDEX  = OFF
        , STATISTICS_NORECOMPUTE  = OFF
        , IGNORE_DUP_KEY = OFF
        , ALLOW_ROW_LOCKS  = ON
        , ALLOW_PAGE_LOCKS  = ON
    ) ON [PRIMARY]
) ON [PRIMARY];

GO

INSERT [dbo].[routePoints] ([idRoutePoints], [idRoute], [idPoint]) VALUES (1, 1, 1);
INSERT [dbo].[routePoints] ([idRoutePoints], [idRoute], [idPoint]) VALUES (2, 1, 2);
INSERT [dbo].[routePoints] ([idRoutePoints], [idRoute], [idPoint]) VALUES (3, 2, 3);
INSERT [dbo].[routePoints] ([idRoutePoints], [idRoute], [idPoint]) VALUES (4, 2, 4);

SET ANSI_NULLS ON;
GO
SET QUOTED_IDENTIFIER ON;
GO

CREATE TABLE [dbo].[points](
    [idPoint] [int] IDENTITY(1,1) NOT NULL,
    [PointName] [nvarchar](50) NOT NULL,
    CONSTRAINT [PK_points] PRIMARY KEY CLUSTERED 
    (
        [idPoint] ASC
    ) WITH (
        PAD_INDEX  = OFF
        , STATISTICS_NORECOMPUTE  = OFF
        , IGNORE_DUP_KEY = OFF
        , ALLOW_ROW_LOCKS  = ON
        , ALLOW_PAGE_LOCKS  = ON
    ) ON [PRIMARY]
) ON [PRIMARY];

GO

SET IDENTITY_INSERT [dbo].[points] ON;

INSERT [dbo].[points] ([idPoint], [PointName]) VALUES (1, N'ACAPULCO');
INSERT [dbo].[points] ([idPoint], [PointName]) VALUES (2, N'ACAPULCO_2');
INSERT [dbo].[points] ([idPoint], [PointName]) VALUES (3, N'MONTERREY');
INSERT [dbo].[points] ([idPoint], [PointName]) VALUES (4, N'MONTERREY_2');

SET IDENTITY_INSERT [dbo].[points] OFF;


SET ANSI_NULLS ON;
GO
SET QUOTED_IDENTIFIER ON;
GO

CREATE TABLE [dbo].[clients]
(
    [idClient] [int] IDENTITY(1,1) NOT NULL,
    [clientName] [nvarchar](50) NULL,
    CONSTRAINT [PK_clients] PRIMARY KEY CLUSTERED 
    (
        [idClient] ASC
    ) WITH (
        PAD_INDEX  = OFF
        , STATISTICS_NORECOMPUTE  = OFF
        , IGNORE_DUP_KEY = OFF
        , ALLOW_ROW_LOCKS  = ON
        , ALLOW_PAGE_LOCKS  = ON
    ) ON [PRIMARY]
) ON [PRIMARY];

GO

SET IDENTITY_INSERT [dbo].[clients] ON;

INSERT [dbo].[clients] ([idClient], [clientName]) VALUES (1, N'Mapple');
INSERT [dbo].[clients] ([idClient], [clientName]) VALUES (2, N'Mocosoft');

SET IDENTITY_INSERT [dbo].[clients] OFF;
War es hilfreich?

Lösung

Es gibt einen (rohen) Hack in SQL Server, um gruppen_concats zu machen, die das erhalten sollten, was Sie benötigen. Im Folgenden finden Sie eine Abfrage für Ihr Beispiel. Ich kann nicht für seine Leistung bürgen, sodass Sie nach Bedarf testen/optimieren müssen.

select idshipment, shortnameroute,
(   
    select pointname +', ' 
    from points p
    inner join routepoints rp on rp.idpoint = p.idpoint
    where rp.idroute = r.idroute  for XML path ('')
), 
c.clientname
from shipments s
inner join [routes] r on r.idroute = s.idroute
inner join clients c on c.idclient = s.idclient
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit dba.stackexchange
scroll top