在SQL视图中使用COALESCE

时间:2010-11-02 20:39:58

标签: sql-server tsql sql-server-2008 coalesce sql-view

我需要从几个表创建一个视图。视图中的一列必须由一个表中的多个行组成,并以逗号分隔值的字符串形式组成。

以下是我想要做的简化示例。

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

因此无论他们是否有订单,所以每个人都会出现在表格中。

我有一个存储过程,我需要转换到这个视图,但似乎你不能声明params并在视图中调用存储过程。有关如何将此查询引入视图的任何建议吗?

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 个答案:

答案 0 :(得分:9)

编辑:修改后的答案,包括创建视图。

/* 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

答案 1 :(得分:6)

在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