我有一个带子查询的复杂SQL查询,它累计要在XSLT中使用的总和。 DB本质上返回XML行,XSL与它们一起工作。现在整个过程都运行得很好,但很遗憾看起来查询中有很多重复,我认为没有必要。
基本上我在子查询中有三次相同的COUNT查询,但是有不同的WHERE语句。一个查询从表中获取全部,一个获取子部分,一个获得不同的子部分。除了两个附加条件之外,查询完全相同。
我已经看过一些使用SUM的解决方案,但由于查询是一个子查询并且包含连接,因此它们确实不起作用。
我选择和加入的表格相当大。其中一个查询计算速度相当快,但是多个相同的选择会大大增加加载时间。
有没有办法组合这些子查询,以便大选择只发生一次而不是3次?
SELECT Matrix.FT_CODE as Code
, ( SELECT COUNT(Partner.TOPIC_ID)
FROM EXP_EXPERTISE_TOPIC AS Partner INNER JOIN KNW_AP AS Expert ON Partner.EXPERTISE_ID = Expert.AP_ID
INNER JOIN AK_PERS AS Person ON Expert.AP_AK_PE_ID = Person.PE_ID
WHERE Matrix.FT_CODE=Partner.TOPIC_ID and AP_DATE_EXPIRED > getdate()
) AS APTotal
, ( SELECT COUNT(Partner.TOPIC_ID)
FROM EXP_EXPERTISE_TOPIC AS Partner INNER JOIN KNW_AP AS Expert ON Partner.EXPERTISE_ID = Expert.AP_ID
INNER JOIN AK_PERS AS Person ON Expert.AP_AK_PE_ID = Person.PE_ID
WHERE (Matrix.FT_CODE BETWEEN substring(Partner.TOPIC_ID,1,5)+'00.00.00.00' AND substring(Partner.TOPIC_ID,1,5)+'99.99.99.99' ) and AP_DATE_EXPIRED > getdate()
) AS APSum2
, ( SELECT COUNT(Partner.TOPIC_ID)
FROM EXP_EXPERTISE_TOPIC AS Partner INNER JOIN KNW_AP AS Expert ON Partner.EXPERTISE_ID = Expert.AP_ID
INNER JOIN AK_PERS AS Person ON Expert.AP_AK_PE_ID = Person.PE_ID
WHERE (Matrix.FT_CODE BETWEEN substring(Partner.TOPIC_ID,1,8)+'00.00.00' AND substring(Partner.TOPIC_ID,1,8)+'99.99.99' ) and AP_DATE_EXPIRED > getdate()
) AS APSum3
FROM BTA_FINAL AS Matrix
WHERE Matrix.FT_CODE BETWEEN '1.00.00.00.00.00' AND '1.99.99.99.99.99'
FOR XML AUTO
此查询是用XML文件编写的,并使用XLS进行渲染,因此在完成数据库后我几乎无法进行数据计算。
示例结果可能如下所示:
<Matrix Code="1.09.17.06.04.00" APTotal="11" APSum2="564" APSum3="75" />
我循环了几百个以生成我的标记。这些数字是条件渲染所必需的。
答案 0 :(得分:0)
在SQL Server中,您可以使用CTE(公用表表达式)而不是子查询。 https://docs.microsoft.com/en-us/sql/t-sql/queries/with-common-table-expression-transact-sql
您可以创建CTE然后应用where子句。这将导致更短更清晰的代码。
答案 1 :(得分:0)
WITH PartnerCTE AS
(
SELECT Partner.TOPIC_ID, Matrix.FT_CODE
FROM EXP_EXPERTISE_TOPIC AS Partner INNER JOIN KNW_AP AS Expert
ON Partner.EXPERTISE_ID = Expert.AP_ID
INNER JOIN AK_PERS AS Person ON Expert.AP_AK_PE_ID = Person.PE_ID
WHERE AP_DATE_EXPIRED > getdate()
)
SELECT Matrix.FT_CODE as Code
, ( SELECT COUNT(TOPIC_ID)
FROM PartnerCTE
WHERE Matrix.FT_CODE=Partner.TOPIC_ID
) AS APTotal
, ( SELECT COUNT(TOPIC_ID)
FROM PartnerCTE
WHERE (Matrix.FT_CODE BETWEEN substring(PartnerCTE.TOPIC_ID,1,5)+'00.00.00.00' AND substring(PartnerCTE.TOPIC_ID,1,5)+'99.99.99.99' )
) AS APSum2
, ( SELECT COUNT(TOPIC_ID)
FROM PartnerCTE
WHERE (Matrix.FT_CODE BETWEEN substring(PartnerCTE.TOPIC_ID,1,8)+'00.00.00' AND substring(PartnerCTE.TOPIC_ID,1,8)+'99.99.99' )
) AS APSum3
FROM BTA_FINAL AS Matrix
WHERE Matrix.FT_CODE BETWEEN '1.00.00.00.00.00' AND '1.99.99.99.99.99'
FOR XML AUTO
和第二个
WITH PartnerCTE AS
(
SELECT Partner.TOPIC_ID, Matrix.FT_CODE
FROM EXP_EXPERTISE_TOPIC AS Partner INNER JOIN KNW_AP AS Expert ON Partner.EXPERTISE_ID = Expert.AP_ID
INNER JOIN AK_PERS AS Person ON Expert.AP_AK_PE_ID = Person.PE_ID
WHERE AP_DATE_EXPIRED > getdate()
)
SELECT
Matrix.FT_CODE as Code,
SUM(CASE
WHEN Matrix.FT_CODE=PartnerCTE.TOPIC_ID THEN 1
ELSE 0
)END APTotal,
SUM(CASE
WHEN Matrix.FT_CODE BETWEEN substring(PartnerCTE.TOPIC_ID,1,5)+'00.00.00.00' AND substring(PartnerCTE.TOPIC_ID,1,5)+'99.99.99.99' THEN 1
ELSE 0
)END APSum2,
SUM(CASE
WHEN Matrix.FT_CODE BETWEEN substring(PartnerCTE.TOPIC_ID,1,8)+'00.00.00' AND substring(PartnerCTE.TOPIC_ID,1,8)+'99.99.99' THEN 1
ELSE 0
)END APSum3,
FROM PartnerCTE, BTA_FINAL AS Matrix
GROUP BY Matrix.FT_CODE
另一次尝试,取消了一些重复的字符串处理:
WITH PartnerCTE AS
(
SELECT
Partner.TOPIC_ID,
LEFT(Partner.TOPIC_ID,5) TOPIC_ID5,
LEFT(Partner.TOPIC_ID,8) TOPIC_ID8,
FROM EXP_EXPERTISE_TOPIC AS Partner INNER JOIN KNW_AP AS Expert ON Partner.EXPERTISE_ID = Expert.AP_ID
INNER JOIN AK_PERS AS Person ON Expert.AP_AK_PE_ID = Person.PE_ID
WHERE AP_DATE_EXPIRED > getdate()
)
SELECT
Matrix.FT_CODE as Code,
SUM(CASE
WHEN Matrix.FT_CODE=PartnerCTE.TOPIC_ID THEN 1
ELSE 0
)END APTotal,
SUM(CASE
WHEN Matrix.FT_CODE BETWEEN TOPIC_ID5+'00.00.00.00' AND TOPIC_ID5+'99.99.99.99' THEN 1
ELSE 0
)END APSum2,
SUM(CASE
WHEN Matrix.FT_CODE BETWEEN TOPIC_ID8+'00.00.00' AND TOPIC_ID8+'99.99.99' THEN 1
ELSE 0
)END APSum3,
FROM PartnerCTE, BTA_FINAL AS Matrix
GROUP BY Matrix.FT_CODE