Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 在另一个表上存在左联接的情况下,使用一个表中的分组结果_Sql_Sql Server_Join - Fatal编程技术网

Sql 在另一个表上存在左联接的情况下,使用一个表中的分组结果

Sql 在另一个表上存在左联接的情况下,使用一个表中的分组结果,sql,sql-server,join,Sql,Sql Server,Join,这是我的第一篇文章,如果你需要更多的细节,请告诉我 我有3个表,其中一个是设置表[invrules],另外2个是成员数据表[basic]和[invinst]。我要做的是使用该方案的唯一值显示[invinst].[invcde]和[invinst].[instamt]列。[invrules]表在[schkey]字段的前4个字符中包含方案代码。我试图做的是,通过将它们分组到该方案中,然后将它们链接到我创建的每个左连接,从而为我提供列,从而确定它们是什么。这需要很长时间才能运行,显然效率不高 我必须将

这是我的第一篇文章,如果你需要更多的细节,请告诉我

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

我必须将其作为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
我尝试使用交叉连接,因为[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的唱片,但有什么大不了的?