Question

Je dois créer une vue de plusieurs tables. L'une des colonnes de la vue devra être composée d'un nombre de lignes de l'un de la table sous forme de chaîne avec des valeurs séparées par des virgules.

Voici un exemple simplifié de ce que je veux faire.

Customers:
CustomerId int
CustomerName VARCHAR(100)

Orders:
CustomerId int
OrderName VARCHAR(100)

Il y a un à plusieurs entre clients et commandes. Donc, étant donné ces données

Customers
1 'John'
2 'Marry'

Orders
1 'New Hat'
1 'New Book'
1 'New Phone'

Je veux une vue d'être comme ceci:

Name     Orders
'John'   New Hat, New Book, New Phone
'Marry'  NULL

Alors que tout le monde apparaît dans la table, indépendamment du fait qu'ils ont des ordres ou non.

J'ai une procédure stockée que je dois traduire ce point de vue, mais il semble que vous ne pouvez pas déclarer params et appelez procs stockés dans une vue. Toutes les suggestions sur la façon d'obtenir cette requête en vue?

CREATE PROCEDURE getCustomerOrders(@customerId int)
AS
   DECLARE @CustomerName varchar(100)
   DECLARE @Orders varchar (5000)

   SELECT @Orders=COALESCE(@Orders,'') + COALESCE(OrderName,'') + ',' 
   FROM Orders WHERE CustomerId=@customerId

   -- this has to be done separately in case orders returns NULL, so no customers are excluded
   SELECT @CustomerName=CustomerName FROM Customers WHERE CustomerId=@customerId

   SELECT @CustomerName as CustomerName, @Orders as Orders
Était-ce utile?

La solution

EDIT :. Réponse modifiée pour inclure la création de vue

/* Set up sample data */
create table Customers (
    CustomerId int,
    CustomerName VARCHAR(100)
)

create table Orders (
    CustomerId int,
    OrderName VARCHAR(100)
)

insert into Customers
    (CustomerId, CustomerName)
    select 1, 'John' union all
    select 2, 'Marry'

insert into Orders
    (CustomerId, OrderName)
    select 1, 'New Hat' union all
    select 1, 'New Book' union all
    select 1, 'New Phone'
go

/* Create the view */       
create view OrderView as    
    select c.CustomerName, x.OrderNames
        from Customers c
            cross apply (select stuff((select ',' + OrderName from Orders o where o.CustomerId = c.CustomerId for xml path('')),1,1,'') as OrderNames) x
go

/* Demo the view */
select * from OrderView
go 

/* Clean up after demo */
drop view OrderView
drop table Customers
drop table Orders
go

Autres conseils

Dans SQL Server 2008, vous pouvez profiter de quelques-unes des fonctionnalités supplémentaires pour XML faire tout cela dans une requête sans utiliser de procédure stockée:

 SELECT CustomerName,
    STUFF( -- "STUFF" deletes the leading ', '
        ( SELECT ', ' + OrderName
        FROM Orders
        WHERE CustomerId = Customers.CutomerId
        -- This causes the sub-select to be returned as a concatenated string
        FOR XML PATH('') 
        ),
    1, 2, '' )
    AS Orders
 FROM Customers
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top