3

我有一个查询,我正在尝试优化,但没有取得太大的成功。有两张表,一张包含主要数据,一张包含特定事件发生时间的时间戳。这些表是使用 adID 的公共键的关系表。我正在尝试执行从主表中提取所有时间戳和其他数据的查询。我让它工作,但我正在尝试优化,以便它运行得更快。

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 不太熟悉,所以我不太擅长优化诸如此类的查询。

4

2 回答 2

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;
于 2013-02-15T20:24:03.103 回答
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
于 2013-02-15T20:10:59.667 回答