2013-02-15 97 views
3

我有一個查詢,我試圖優化但沒有太多成功。有兩張表,一張是主要數據,另一張是特定事件發生時的時間戳。這些表格使用adID的公共密鑰進行關聯。我試圖執行一個查詢,從主表中獲取所有時間戳和其他數據。我有它的工作,但我想優化,所以它運行得更快。如何優化具有多個子查詢的SELECT語句

SELECT a.ID,a.repID,a.artistID, 
(
    SELECT TOP 1 c.timestamp 
    FROM Tracking AS c 
    WHERE statusID = 4 
    AND c.ID = a.ID 
    ORDER BY c.timestamp ASC 

) 
AS created, 
(
    SELECT TOP 1 d.timestamp 
    FROM Tracking AS d 
    WHERE statusID = 5 
    AND d.ID = a.ID 
    ORDER BY d.timestamp ASC 
) 
AS claimed, 
(
    SELECT TOP 1 p.timestamp 
    FROM Tracking AS p 
    WHERE statusID = 6 
    AND p.ID = a.ID 
    ORDER BY p.timestamp ASC 
) 
AS proof, 
(
    SELECT TOP 1 v.timestamp 
    FROM Tracking AS v 
    WHERE statusID = 8 
    AND v.ID = a.ID 
    ORDER BY v.timestamp ASC 
) 
AS approved, 
(
    SELECT count(ID) 
    FROM Tracking AS t 
    WHERE statusID = 6 
    AND t.ID = a.ID 
) 
AS proofcount 
FROM Advertising AS a 
WHERE a.statusID = 8 

對此的任何幫助表示讚賞。我對SQL Server不太熟悉,所以我不太熟悉如何優化這些查詢。

+0

有多少行呢查詢回報? 「Tracking」有哪些索引? – 2013-02-15 20:09:36

回答

2

您應該能夠使用以下命令:

SELECT a.ID, 
    a.repID, 
    a.artistID, 
    min(case when t.statusID = 4 then t.timestamp end) created, 
    min(case when t.statusID = 5 then t.timestamp end) claimed, 
    min(case when t.statusID = 6 then t.timestamp end) proof, 
    min(case when t.statusID = 8 then t.timestamp end) approved, 
    count(case when t.statusID = 6 then id end) proofcount 
FROM Advertising AS a 
LEFT JOIN Tracking t 
    on a.id = t.id 
WHERE a.statusID = 8 
GROUP BY a.ID, a.repID, a.artistID; 
+0

謝謝bluefeet。這就像一個魅力。 – jgraening 2013-02-15 20:30:51

+0

@jgraening不客氣,我很樂意提供幫助。這基本上是一個'PIVOT',你也可以實現這個功能來執行這個任務。 – Taryn 2013-02-15 20:31:41

1

我認爲以下查詢獲取你想要什麼:

select id, repid, artistid, 
     max(case when statusId = 4 and seqnum = 1 then timestamp end), 
     max(case when statusId = 5 and seqnum = 1 then timestamp end), 
     max(case when statusId = 6 and seqnum = 1 then timestamp end), 
     max(case when statusId = 8 and seqnum = 1 then timestamp end), 
     sum(case when statusId = 6 then 1 else 0 end) 
from (select a.ID, a.repID, a.artistID, t.statusId, t.timestamp 
      row_number() over (partition by a.id, t.statusId order by timestamp) as seqnum 
     from advertising a left outer join 
      tracking t 
      on a.id = t.id 
    ) t 
where seqnum = 1 
group by id, repid, artistid 

它加入表一起,並確定使用row_number()的最早記載。然後它將只選​​擇其他字段的這些記錄和組。

您的查詢也只篩選那些有statusid = 8的記錄。我不確定這是否是故意的。如果是這樣,那麼你想查詢的結束這個having條款:

having sum(case when statusId = 8 then 1 else 0 end) > 0