我有这个SQL查询:
WITH CTE(documents, pocname, pocphone, initialticketNo)
AS
(
SELECT
SO.Documents, SO.POCName, SO.POCPhone,
SUBSTRING(SO.Documents, 0, CHARINDEX('-', SO.Documents)) AS 'InitialCustomerTicket'
FROM
ServiceOrder SO
CROSS APPLY
(SELECT
COUNT(TECHNICIANTRIPDETAILID) TTL
FROM
TECHNICIANTRIPDETAIL
WHERE
SERVICEORDERID = SO.SERVICEORDERID
AND ISEQUIPMENTREPAIRED = 1) EQUIPMENT
INNER JOIN
Contract CON ON CON.ContractId = SO.ContractId
INNER JOIN
ClientProfile CP ON CP.ClientId = CON.ClientId
WHERE
CP.ClientId = 20739
AND SO.CloseStatus = 1
AND equipment.ttl > 0
AND ISNULL(SO.DOCUMENTS,'') <> ''
)
SELECT *
FROM cte
WHERE initialticketNo <> ''
现在在上面的查询中,如果你看到我已经计算了一个字段initialticketno。我想在同一个表serviceorder上再次运行查询,并希望计数以initialticketno开头的每个票号。当我这样做时,它需要花费很多时间,有什么方法可以简化这个查询吗?
WITH CTE(documents,pocname,pocphone,initialticketNo)
as
(Select SO.Documents,SO.POCName,SO.POCPhone,
SUBSTRING(SO.Documents,0,CHARINDEX('-',SO.Documents)) AS 'InitialCustomerTicket'
From ServiceOrder SO
CROSS APPLY (SELECT COUNT(TECHNICIANTRIPDETAILID) TTL FROM TECHNICIANTRIPDETAIL WHERE SERVICEORDERID = SO.SERVICEORDERID AND ISEQUIPMENTREPAIRED = 1) EQUIPMENT
Inner Join Contract CON ON CON.ContractId = SO.ContractId
Inner Join ClientProfile CP ON CP.ClientId = CON.ClientId
where CP.ClientId = 20739 AND SO.CloseStatus = 1 and equipment.ttl > 0 AND ISNULL(SO.DOCUMENTS,'') <> '')
select * from cte
cross apply (select count(serviceorderid) ttl from serviceorder so where so.documents like cte.initialticketNo + '%') as so
where initialticketNo <> '' and so.ttl > 1
PS:serviceorder表中的总记录为75k。
任何人都可以帮我这个。
答案 0 :(得分:0)
我敢打赌,如果索引很慢而你的数据集很小,那么你就错过了索引。我认为这个查询会产生相同的输出,但我认为它会更有效。
SELECT DISTINCT
SO.Documents, SO.POCName, SO.POCPhone,
SUBSTRING(SO.Documents, 0, CHARINDEX('-', SO.Documents)) AS 'InitialCustomerTicket'
FROM ServiceOrder SO
INNER JOIN Contract CON ON CON.ContractId = SO.ContractId
INNER JOIN ClientProfile CP ON CP.ClientId = CON.ClientId
INNER JOIN TECHNICIANTRIPDETAIL TTD ON TTD.SERVICEORDERID = SO.SERVICEORDERID
AND TTD.ISEQUIPMENTREPAIRED = 1
WHERE
CP.ClientId = 20739
AND SO.CloseStatus = 1
AND ISNULL(SO.DOCUMENTS,'') <> ''
and SUBSTRING(SO.Documents, 0, CHARINDEX('-', SO.Documents)) <> ''
答案 1 :(得分:0)
问题是Cross Apply
。那将是每行运行该查询,因此可能是75k次。有两个交叉适用至少是坏的两倍;)
第一个查询可以像这样重写
SELECT
SO.Documents, SO.POCName, SO.POCPhone,
SUBSTRING(SO.Documents, 0, CHARINDEX('-', SO.Documents)) AS 'InitialCustomerTicket'
FROM
ServiceOrder SO
join TECHNICIANTRIPDETAIL on SERVICEORDERID = SO.SERVICEORDERID AND ISEQUIPMENTREPAIRED = 1 as 'EQUIPMENT'
INNER JOIN
Contract CON ON CON.ContractId = SO.ContractId
INNER JOIN
ClientProfile CP ON CP.ClientId = CON.ClientId
WHERE
CP.ClientId = 20739
AND SO.CloseStatus = 1
AND ISNULL(SO.DOCUMENTS,'') <> ''
Group by SO.Documents, SO.POCName, SO.POCPhone,
SUBSTRING(SO.Documents, 0, CHARINDEX('-', SO.Documents)) AS 'InitialCustomerTicket'
having count(equipment.TECHNICIANTRIPDETAILID) > 0
第二个可以这样写:
SELECT
SO.Documents, SO.POCName, SO.POCPhone,
SUBSTRING(SO.Documents, 0, CHARINDEX('-', SO.Documents)) AS 'InitialCustomerTicket'
FROM
ServiceOrder SO
join TECHNICIANTRIPDETAIL on SERVICEORDERID = SO.SERVICEORDERID AND ISEQUIPMENTREPAIRED = 1 as 'EQUIPMENT'
INNER JOIN
Contract CON ON CON.ContractId = SO.ContractId
INNER JOIN
ClientProfile CP ON CP.ClientId = CON.ClientId
join serviceorder as SO2 on so2.documents like so.initialticketNo + '%'
WHERE
CP.ClientId = 20739
AND SO.CloseStatus = 1
AND ISNULL(SO.DOCUMENTS,'') <> ''
Group by SO.Documents, SO.POCName, SO.POCPhone,
SUBSTRING(SO.Documents, 0, CHARINDEX('-', SO.Documents)) AS 'InitialCustomerTicket'
having count(equipment.TECHNICIANTRIPDETAILID) > 0
and count(so2.serviceorderid) > 1
当然,我之前和之后都无法运行,因为我没有数据,但我认为应该这样做。如果不是,它至少可以让您知道在哪里前进 - 尽可能删除Cross Apply
。
答案 2 :(得分:0)
这是一个更简单且(可能更有效)的查询:
SELECT SO.Documents ,
SO.POCName ,
SO.POCPhone ,
SUBSTRING(SO.Documents, 0, CHARINDEX('-', SO.Documents)) AS initialticketNo
FROM ClientProfile CP
INNER JOIN [Contract] CON ON CON.ClientId = CP.ClientId
INNER JOIN ServiceOrder SO ON SO.ContractId = CON.ContractId
WHERE CP.ClientId = 20739
AND SO.CloseStatus = 1
AND SO.Documents IS NOT NULL
AND SO.Documents LIKE '%-%'
AND EXISTS ( SELECT *
FROM TECHNICIANTRIPDETAIL TTL
WHERE TTL.ISEQUIPMENTREPAIRED = 1
AND TTL.SERVICEORDERID = SO.SERVICEORDERID )