SQL Server:用联接视图替换UDF

时间:2016-01-20 23:01:47

标签: sql-server join sql-server-2012

对于SQL Server,我想问一下我脑袋里的gordian结。我正在尝试用连接视图替换UDF,但我很难让视图返回我需要的东西。一点点巧妙的排序或许可以做到这一点,我被困住了。

不幸的是我现在无法注册SQL小提琴,所以我必须在这里提供测试数据:

CREATE TABLE #Contacts
(
     ID INT NOT NULL IDENTITY, 
     Firstname VARCHAR(50) NULL, 
     Lastname VARCHAR(50) NULL
)
GO

CREATE TABLE #Cars (ID INT NOT NULL IDENTITY, CarModel VARCHAR(50) NULL)
GO

CREATE TABLE #Ownership
(
     Contacts_ID INT NOT NULL, 
     cars_id INT NOT NULL, 
     ownership_type TINYINT NOT NULL, 
     DisplayName VARCHAR(50) NULL
)
GO

CREATE TABLE #Races(ID INT NOT NULL IDENTITY, RaceName VARCHAR(50) NOT NULL)
GO

CREATE TABLE #RaceEntries 
( 
     ID INT NOT NULL IDENTITY, 
     Races_ID INT NOT NULL, 
     Contacts_ID INT NOT NULL, 
     cars_id INT NOT NULL
)

INSERT [#Contacts] ([Firstname], [Lastname])
SELECT
'Justin', 'Case' UNION ALL SELECT
'Gladys', 'Friday' UNION ALL SELECT
'Mandy', 'Lifeboats'
GO

INSERT [#Cars] ([CarModel])
VALUES  ('Great Car')
GO

INSERT [#Races] ([RaceName])
VALUES  ('A Car Race')

INSERT [#Ownership] ([Contacts_ID], [cars_id], [ownership_type], [DisplayName]) SELECT
1, 1, 0, NULL UNION ALL SELECT
2, 1, 1, NULL UNION ALL SELECT
3, 1, 1, 'Mandy Lifeboats Racing Team'

INSERT [#RaceEntries] ([Races_ID], [Contacts_ID], [cars_id]) SELECT
1, 1, 1 UNION ALL SELECT
1, 3, 1 UNION ALL SELECT
1, 2, 1

我想要的是什么:

SELECT 
    [cars_id], mvo.Ownername 
FROM 
    [#RaceEntries] -- join a view that returns the ownername
LEFT OUTER JOIN 
    #myViewOwnername AS mvo ON mvo.Contacts_ID = [#RaceEntries].[Contacts_ID] AND mvo.Cars_ID = [#RaceEntries].[cars_id]

这里的问题是每辆车只有一个所有者(所有权类型为0)。它可以有其他联系人作为代表。

通常在#RaceEntries的列表中,显示所有者的姓名,除非代表具有约定的“覆盖”(以便显示他或公司名称)。

在上面的例子中,Justin Case的参赛作品是直截了当的。他是所有者(0型),故事结束。

当Gladys Friday进入时(她没有覆盖“DisplayName”),系统应该再次返回Justin Case的名字作为拥有者。

在最后一个例子中,Mandy Lifeboats有一个DisplayName,因此应该返回。

理想情况下,我最终会得到一个重要的视图或类似信息,以便我可以将其加入#RaceEntries的x000记录(加入汽车和联系人ID)以获得正确的所有者名称。

我希望我尽可能地简化了这个例子,真实的东西有点复杂......请让我知道我是否应该准备其他任何东西以帮助更​​容易一些。非常感谢!

1 个答案:

答案 0 :(得分:1)

我认为这可能就是你要找的东西:

select [#Ownership].Contacts_ID, 
    [#Ownership].Cars_ID,
    coalesce([DisplayName], CarOwners.ContactName) Ownername
into #myViewOwnername
from [#Ownership]
join
    (
    select [cars_id], Contacts_ID, [#Contacts].Firstname + ' ' + [#Contacts].Lastname ContactName
    from [#Ownership]
    join [#Contacts]
    on [#Ownership].Contacts_ID = [#Contacts].ID
    where ownership_type = 0
    ) CarOwners
on [#Ownership].cars_id = CarOwners.cars_id

汽车有一个直接拥有者(类型0),因此子查询将获取每辆汽车的所有车主姓名。然后,您只需将其加入ownership字段中的cars_id表格即可。如果ownership表中有显示名称,则显示该名称,否则显示车主姓名。