假设我有两张表Contracts
和ServiceProviders
。合同具有引用服务提供商的属性LeadServiceProvider
。
我还有一个名为SubServiceProviders
的第三个表,它在Contracts
和ServiceProviders
之间保持多对多关系,充当子服务提供商。
我想在Contract上运行一个查询,它会在一列中为我提供所有服务提供商的列表 - Lead和Sub:
Select
c.LeadServiceProvider, subSP.ServiceProvider
From
Contracts c
left join
SubServiceProviders subSP on c.ID = subSP.Contract
Where
[Some contract criteria goes here]
上面的查询为我提供了两列,理想情况下,我希望将其展平为一个并运行distinct()
。我可以选择LeadServiceProvider
,然后UNION
选择SubServiceProviders
。
对于这个示例来说这很简单,但是,在我的实际应用中,FROM
和WHERE
子句非常复杂,如果我要使用UNION
,我就是我不得不重复这些条款
答案 0 :(得分:2)
如果您正在寻找一种在一个查询中执行此操作的简单方法,则可以使用CTE并取消列。我会用join
这样明确地做到这一点:
with t as (
Select c.LeadServiceProvider, subSP.ServiceProvider
From Contracts c left join SubServiceProviders subSP on c.ID = subSP.Contract
Where [Some contract criteria goes here]
)
select distinct (case when n.n = 1 then LeadServiceProvider else ServiceProvider end) as SP
from t cross join
(select 1 as n union all select 2) n;
编辑:
您可以轻松地将其放入子查询中:
select distinct (case when n.n = 1 then LeadServiceProvider else ServiceProvider end) as SP
from (<your query here without the order by>) t cross join
(select 1 as n union all select 2) n;
或者忘记子查询:
Select distinct (case when n.n = 1 then c.LeadServiceProvider
else subSP.ServiceProvider
end)
From Contracts c left join
SubServiceProviders subSP
on c.ID = subSP.Contract cross join
(select 1 as n union all select 2) n
Where [Some contract criteria goes here]
答案 1 :(得分:0)
The query above gives me two colums that, ideally, I would flatten into
one and run a distinct() on
如果我正确地理解你......为什么不做这样的事情。您需要将上述查询区分开来......
Select DISTINCT * from (
Select c.LeadServiceProvider, subSP.ServiceProvider
From Contracts c left join SubServiceProviders subSP on c.ID = subSP.Contract
Where [Some contract criteria goes here]) aliasname
这会给你上面的查询但只有不同的项目。 注意:尚未通过任何编辑器运行,因此我没有验证语法
答案 2 :(得分:0)
在Oracle SQL中,您始终可以使用normal with命令来消除多次使用同一个表的需要,然后将它们连接在一起
答案 3 :(得分:0)
这样的东西?
select distinct id, ServiceProvider from (
(Select distinct
id, LeadServiceProvider as ServiceProvider, 1 as isLead, otherWhereCriteria
From
Contracts ) l
union all
(Select distinct
Contract, ServiceProvider, 0 as isLead, otherWhereCriteria
From
Contracts c inner join
SubServiceProviders s on c.ID = s.Contract) s
) u
Where
otherWhereCriteria = targetValues
答案 4 :(得分:0)
这似乎是使用unpivot
的理想时间:
SELECT DISTINCT subpvt.serviceprovider
FROM (SELECT c.leadserviceprovider, subsp.serviceprovider, c.id
FROM contracts c
LEFT JOIN subserviceproviders subsp ON c.id = subsp.contract
WHERE /*Some contract criteria goes here*/
) p UNPIVOT (id
FOR serviceprovider
IN (leadserviceprovider, serviceprovider)) subpvt
警告:这是未经测试的,因为操作系统没有提供样本数据,我不愿意制造任何数据。
答案 5 :(得分:0)
似乎你可以在这里使用CROSS APPLY:
Select distinct
v.ServiceProvider
From
Contracts c
left join
SubServiceProviders subSP on c.ID = subSP.Contract
cross apply
(values (c.LeadServiceProvider), (subSP.ServiceProvider)) as v (ServiceProvider)
Where
[Some contract criteria goes here]
SQL Server 2005及更高版本,SQL Server 2008及更高版本中的CROSS APPLY行构造函数支持VALUES。您可以使用等效的UNION ALL子查询替换VALUES子句,以使查询与SQL Server 2005兼容:
(
select c.LeadServiceProvider
union all
select subSP.ServiceProvider
) as v (ServiceProvider)