Sql 在另一个表上存在左联接的情况下,使用一个表中的分组结果
这是我的第一篇文章,如果你需要更多的细节,请告诉我 我有3个表,其中一个是设置表[invrules],另外2个是成员数据表[basic]和[invinst]。我要做的是使用该方案的唯一值显示[invinst].[invcde]和[invinst].[instamt]列。[invrules]表在[schkey]字段的前4个字符中包含方案代码。我试图做的是,通过将它们分组到该方案中,然后将它们链接到我创建的每个左连接,从而为我提供列,从而确定它们是什么。这需要很长时间才能运行,显然效率不高 我必须将其作为SELECT语句来执行,而不是使用CTE或函数 这是一次花费了很长时间才在几分钟内给出正确结果的尝试:Sql 在另一个表上存在左联接的情况下,使用一个表中的分组结果,sql,sql-server,join,Sql,Sql Server,Join,这是我的第一篇文章,如果你需要更多的细节,请告诉我 我有3个表,其中一个是设置表[invrules],另外2个是成员数据表[basic]和[invinst]。我要做的是使用该方案的唯一值显示[invinst].[invcde]和[invinst].[instamt]列。[invrules]表在[schkey]字段的前4个字符中包含方案代码。我试图做的是,通过将它们分组到该方案中,然后将它们链接到我创建的每个左连接,从而为我提供列,从而确定它们是什么。这需要很长时间才能运行,显然效率不高 我必须将
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
我尝试使用交叉连接,因为[invinst]表不需要连接任何内容。这将从每行的[basic]表返回数据,并从[invinst]表返回匹配数据,但由于交叉联接,在从[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]表,并在左侧联接中使用该表,从而提高效率?还是有不同的方法
谢谢
Darrell如果您想将'basic'与'invinst'连接起来,而'invinst'又与'invrules'连接起来,那么只需这样做 使用嵌套联接,而不是“平面联接” 基本上,前三个连接没有连接 UPD:试试这样的
SELECT getdate() AS DateRun,
member_no
member_surname,
scheme,
investment_code,
investment_percentage,
percentage_rank
FROM (
SELECT
b.membno AS member_no,
b.surnam AS member_surname,
b.scheme AS scheme,
i.invcde AS Investment_Code,
i.instamt AS Investment_Percentage,
RANK() OVER (PARTITION BY b.membno ORDER BY i.instamt) AS percentage_rank
FROM basic AS b
LEFT JOIN invinst AS i ON b.membno = i.membno
LEFT JOIN invcde_list AS il ON i.invcde = il.invcde
WHERE b.membno >= 15000
AND b.scheme = 'ABCD'
AND i.contsrc = 'EE'
AND i1.enddte IS NULL
) as FinallyJoined
WHERE percentage_rank < 4;
这可能不太管用,我还没有MSSQL,但我希望你能理解。看起来是一个很好的枢轴案例,但你可能想从一个更简单、更容易理解的例子开始。谢谢Aaron,我将探讨枢轴如何帮助我。谢谢。Yuri,你是说invinst连接中的嵌套连接吗?我不确定是否有比在每个表中都使用嵌套联接更优雅的方法,因为我似乎在重复invrules表。如果你有一个简单的例子,那就很方便了,谢谢。查询将有来自联接表的多个行,OP似乎希望这些行显示为单独的列,而不是行。Darrell,我的意思是,实际上你将invinst与invrules联接,然后再与basic联接,至少,这就是您在b.membno=i1.membno和i1.invcde=[invcde\u list\u 1]上的规则。invcde建议让引擎更清楚,并以正确的顺序排列这些联接。然后,随着混乱程度的下降,这将更容易进一步思考。尽管您试图做的并不适合关系模型。为什么不得到三条记录而不是一条?我的意思是,将这三个表连接一次,对整个查询应用秩,并将其限制为3。你会有三张同样的b.membno,b.surnam,b.scheme的唱片,但有什么大不了的?