Использование Coalesce в SQL View
-
28-09-2019 - |
Вопрос
Мне нужно создать вид с нескольких таблиц. Один из колонн в представлении должен быть состоит из нескольких строк из одной из таблиц в виде строки с разделенными запятыми значениями.
Вот упрощенный пример того, что я хочу сделать.
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
Так что все проявляются в таблице, независимо от того, имеют ли у них заказы или нет.
У меня есть сохраненная процедура, которую мне нужно перевести на этот вид, но кажется, что вы не можете объявить параметрами и вызовите сохраненные Procs в рамках просмотра. Любые предложения о том, как получить этот запрос на вид?
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
Решение
РЕДАКТИРОВАТЬ: Модифицированный ответ, чтобы включить создание просмотра.
/* 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
Другие советы
В SQL Server 2008 вы можете воспользоваться дополнительными функциями, добавленными для XML, чтобы сделать это все в одном запросе без использования сохраненного ProC:
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