温馨提示:本文翻译自stackoverflow.com,查看原文请点击:sql server - Select with multiple subselects on same table with parent-children like relations
sql-server sql-server-2016 tsql

sql server - 在具有父子关系的同一表上具有多个子选择进行选择

发布于 2020-04-09 10:09:34

我有一个表,其中包含机器上的数据。除其他外,还有(唯一)设备编号(EMEQP#),财务成本(EMCOST),当前值(EMBOOK)和设备链接(EMLEQP)的列。某些计算机由其他几台计算机组成,通过将“父”计算机的EMEQP#放在EMLEQP列中来链接这些计算机。父级的EMLEQP有时会被填充(带有其自己的EMEQP#),但也可以为空。同样,不是每个父母都有孩子,但是即使这样,也可以填写或不填写EMLEQP。

这是数据的简化示例:

EMEQP#    |  EMLEQP  |  EMCOST  |  EMBOOK  
ACMD001   |  ACMD001 |  10      |  12  
ACMD001A  |  ACMD001 |  8       |  1  
ACMD002   |  NULL    |  10      |  12  
SLE003    |  NULL    |  11      |  5
RUP5120   |  SLE003  |  12      |  7  

因此,在这种情况下,ACMD001,ACMD002和SLE003是父计算机(因为EMLEQP为空或与EMEQP#相同。ACMD001A是ACMD001的子代,而RUP5120是SLE003的子代。

查询结果应为:

EMEQP#   |  EMCOST  |  EMBOOK  
ACMD001  |  18      |  13  
ACMD002  |  10      |  12  
SLE003   |  23      |  12

我需要知道每台计算机的总EMCOST和EMBOOK,因此要知道父级和任何子级的总和。最初,我尝试group by在EMLEQP上使用,但此方法不起作用,因为在父级上可能为空。
接下来,我尝试使用子查询。主查询会选择所有WHERE EMLEQP = EMEQP# OR EMLEQP = ''父节点),子查询会计算所有计算机的总和,其中EMLEQP是父节点的EMEQP#(或者为空以包括父节点)。到目前为止,这是我计算EMCOST总和的结果。

SELECT EMEQP#, (SELECT SUM(b.emcost) FROM uv_EQPMASFL AS b WHERE (b.emleqp = a.emeqp# AND b.emeqp# <> a.emeqp# OR b.emeqp# = a.emeqp#) 'EMCOST' FROM uv_EQPMASFL a WHERE (EMLEQP = EMEQP# or EMLEQP = '')

该查询有效,但是非常慢。运行它需要15分钟以上,我什至还没有添加第二笔款项。由于我不能在子查询中使用两列,因此我将需要添加第二个子查询以获取第二个总和。最后,如果我可以再获得一列来指示作为父级(包括父级)一部分的计算机的数量,我也希望这样做。

必须有一种更好,更有效的方法来获取此数据,但是我不知道如何。

查看更多

提问者
Nils Tiebos
被浏览
64
Nils Tiebos 2020-02-04 17:18

根据@XAMT的建议,我采取了另一种方法并能够解决此问题。
任何有兴趣,我第一次SELECT的数据,其中EMLEQP不为空(所以所有的孩子和家长在EMLEQP自己EMEQP#,然后UNION与一个SELECT地方EMLEQP是空的数据。
从这个选择我又向SELECTGROUP BYEMEQP#