Использование COALESCE в представлении SQL - PullRequest
9 голосов
/ 02 ноября 2010

Мне нужно создать представление из нескольких таблиц.Один из столбцов в представлении должен состоять из ряда строк одной таблицы в виде строки с разделенными запятыми значениями.

Вот упрощенный пример того, что я хочу сделать.

Customers:
CustomerId int
CustomerName VARCHAR(100)

Orders:
CustomerId int
OrderName VARCHAR(100)

Между Клиентом и Заказами существует отношение один ко многим.Поэтому, учитывая эти данные

Customers
1 'John'
2 'Marry'

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

, я хочу, чтобы представление было таким:

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

Так, чтобы ВСЕ отображались в таблице независимо от того, есть у них заказы или нет.1012 *

У меня есть хранимая процедура, которую мне нужно перевести в это представление, но кажется, что вы не можете объявлять параметры и вызывать хранимые процедуры в представлении.Любые предложения о том, как получить этот запрос в представлении?

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

Ответы [ 2 ]

9 голосов
/ 02 ноября 2010

РЕДАКТИРОВАТЬ : измененный ответ для включения создания представления.

/* 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
6 голосов
/ 02 ноября 2010

В SQL Server 2008 вы можете воспользоваться некоторыми функциями, добавленными для XML, чтобы сделать все это в одном запросе без использования сохраненного процесса:

 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
...