在另一个表

时间:2017-02-08 18:58:41

标签: sql sql-server join

这是我的第一篇文章,如果您需要更多详细信息,请与我们联系。

我有3个表,其中一个是设置表[invrules],然后另外两个是成员数据表[basic][invinst]。我想要做的是使用该方案的唯一值显示[invinst].[invcde][invinst].[instamt]列。 [invrules]表的字段[schkey]的前4个字符中包含方案代码。我试图做的是通过将它们分组为该方案来确定它们是什么,然后将其链接到我创建的每个LEFT JOIN以给我列。这需要很长时间才能运行,显然效率不高。

我必须将此作为SELECT语句而不是使用CTE或函数。

这是花费很长时间才能提供正确结果的尝试(几分钟):

select getdate() DateRun
    ,b.membno
    ,b.surnam
    ,b.scheme
    ,i1.invcde AS 'Investment Code 1'
    ,i1.instamt AS 'Investment Percentage 1'
    ,i2.invcde AS 'Investment Code 2'
    ,i2.instamt AS 'Investment Percentage 2'
    ,i3.invcde AS 'Investment Code 3'
    ,i3.instamt AS 'Investment Percentage 3'
from basic AS b
left join
(
    select i.invcde, RANK() OVER (ORDER BY i.invcde) AS [RANK]
    from invrules AS i
    where left(schkey, 4) = 'ABCD'
    and (i.enddte is null or i.enddte > getdate())
    group by i.invcde
) AS [invcde_list_1] ON [invcde_list_1].Rank = 1
left join
(
    select i.invcde, RANK() OVER (ORDER BY i.invcde) AS [RANK]
    from invrules AS i
    where left(schkey, 4) = 'ABCD'
    and (i.enddte is null or i.enddte > getdate())
    group by i.invcde
) AS [invcde_list_2] ON [invcde_list_2].Rank = 2
left join
(
    select i.invcde, RANK() OVER (ORDER BY i.invcde) AS [RANK]
    from invrules AS i
    where left(schkey, 4) = 'ABCD'
    and (i.enddte is null or i.enddte > getdate())
    group by i.invcde
) AS [invcde_list_3] ON [invcde_list_3].Rank = 3
left join invinst AS i1 on b.membno = i1.membno and i1.invcde = [invcde_list_1].invcde and i1.contsrc = 'EE' and i1.enddte is null and [invcde_list_1].Rank = 1
left join invinst AS i2 on b.membno = i2.membno and i2.invcde = [invcde_list_2].invcde and i2.contsrc = 'EE' and i2.enddte is null and [invcde_list_2].Rank = 2
left join invinst AS i3 on b.membno = i3.membno and i3.invcde = [invcde_list_3].invcde and i3.contsrc = 'EE' and i3.enddte is null and [invcde_list_3].Rank = 3
where b.membno >= 15000
and b.scheme = 'ABCD'
order by b.membno

我尝试使用CROSS JOIN,因为[invinst]表格不需要加入任何内容。这返回了每行[basic]表中的数据以及来自[invinst]表的匹配数据,但由于CROSS JOIN列中的Null值,因此还有其他行派生自[invinst]表。这是代码:

select getdate() DateRun
    ,b.membno
    ,b.surnam
    ,b.scheme
    ,i1.invcde AS 'Investment Code 1'
    ,i1.instamt AS 'Investment Percentage 1'
    ,i2.invcde AS 'Investment Code 2'
    ,i2.instamt AS 'Investment Percentage 2'
    ,i3.invcde AS 'Investment Code 3'
    ,i3.instamt AS 'Investment Percentage 3'
from basic AS b
cross join
(
    select i.invcde, RANK() OVER (ORDER BY i.invcde) AS [RANK]
    from invrules AS i
    where left(dcschkey, 4) = 'ABCD'
    and (i.enddte is null or i.enddte > getdate())
    group by i.invcde
) AS [invcde_list]
left join invinst AS i1 on b.membno = i1.membno and i1.invcde = [invcde_list].invcde and i1.contsrc = 'EE' and i1.enddte is null and [invcde_list].Rank = 1
left join invinst AS i2 on b.membno = i2.membno and i2.invcde = [invcde_list].invcde and i2.contsrc = 'EE' and i2.enddte is null and [invcde_list].Rank = 2
left join invinst AS i3 on b.membno = i3.membno and i3.invcde = [invcde_list].invcde and i3.contsrc = 'EE' and i3.enddte is null and [invcde_list].Rank = 3
where b.membno >= 15000
and b.scheme = 'ABCD'
order by b.membno

这是一些测试数据:

[basic]
membno  surnam  scheme
14000   Jones   ABCD
15000   Smith   ABCD
15001   Henry   ABCD
15002   Mabel   ABCD
15003   McDonald    ABCD

[invinst]
membno  contsrc invcde  instamt
14000   EE  CD01    100
15000   EE  CD01    50
15000   EE  CD02    50
15000   ER  CD01    50
15001   EE  CD02    100
15002   EE  CD01    100
15003   EE  CD01    100
15003   ER  CD01    100

[invrules]
schkey  contsrc enddte  invcde
ABCDCAT1    EE      CD01
ABCDCAT1    ER      CD01
ABCDCAT1    EE      CD02
ABCDCAT1    ER      CD02
ABCDCAT1    EE      CD03
ABCDCAT1    ER      CD03
ABCDCAT2    EE      CD01
ABCDCAT2    ER      CD01
ABCDCAT2    EE      CD02
ABCDCAT2    ER      CD02
ABCDCAT2    EE      CD03
ABCDCAT2    ER      CD03
ABCDCAT3    EE      CD01
ABCDCAT3    EE      CD02
ABCDCAT3    EE      CD03
ABCDCAT4    EE      CD01
ABCDCAT4    EE      CD02
ABCDCAT4    EE      CD03
ABBBCAT1    EE      CD01
ABBBCAT1    EE      CD02
ABBBCAT2    EE      CD01
ABBBCAT3    EE      CD01

我不得不稍微修改数据以对其进行匿名处理,但希望您能理解我想要实现的目标。

如果不使用大量子查询,我可以总结方案的[invrules]表,并在LEFT JOIN s中使用更有效的方法吗?或者有不同的方法吗?

谢谢,

达雷尔

1 个答案:

答案 0 :(得分:-1)

如果你想加入'基本'和'invinst'加入'invrules' - 那么就这样做吧!

使用嵌套连接,而不是“平坦”。

基本上,你的前三个加入什么都没有。

UPD :尝试这样的事情

MPI_Sendrecv

可能没有完全正常工作,我没有MSSQL可及 - 但我希望你有这个想法。