我有一個表(可以稱之爲audit
),看起來像這樣:選擇從範圍內的最低日期和排除另一個範圍
+--------------------------------------------------------------------------+
| id | recordId | status | mdate | type | relatedId |
+--------------------------------------------------------------------------+
| 1 | 3006 | A | 2013-04-03 23:59:01.275 | type1 | 1 |
| 2 | 3025 | B | 2013-04-04 00:00:02.134 | type1 | 1 |
| 3 | 4578 | A | 2013-04-04 00:04:30.033 | type2 | 1 |
| 4 | 7940 | C | 2013-04-04 00:04:32.683 | type1 | <NULL> |
| 5 | 3006 | D | 2013-04-04 00:04:32.683 | type1 | <NULL> |
| 6 | 4822 | E | 2013-04-04 00:04:32.683 | type2 | <NULL> |
| 7 | 3006 | A | 2013-04-04 00:06:54.033 | type1 | 2 |
| 8 | 3025 | C | 2013-04-04 00:06:54.033 | type1 | 2 |
...和對數百萬行的。而另一張表,我們將撥打related
:
+-------------+
| id | source |
+-------------+
| 1 | src_X |
| 2 | src_Y |
| 3 | src_Z |
| 4 | src_X |
| 5 | src_X |
......並開啓數十萬行。
這兩個表格上的列數多於這些列,但這是我們需要描述問題的全部內容。列relatedId
加入related
表。 recordId
也加入到另一個表中,並且audit
中將有多個條目與recordId
相同。
我試圖創建將產生以下輸出的查詢:
+-----------------+
| source | count |
+-----------------+
| src_X | 1643 |
| src_Y | 255 |
| NULL | 729 |
+-----------------+
的計數的記錄中audit
數量已經給定type
(如"type1"
),是一個集內的狀態(例如,"A", "B", "C"
),然後將其外部加入related
並按source
分組。
美中不足的是,我只希望包括audit
是在特定日期範圍內的內記錄,而我也只是想從audit
加入到related
在該範圍內,最早的條目爲每個recordId
。此外,我想忽略任何與type
和status
條件匹配的記錄,但是具有相同的recordId
的條目比日期範圍更早。
所以,從上面的例子中的數據闡明:可以說,我想的類型的type1
和"A", "B", "C"
與2013-04-04
到2013-04-05
日期範圍的狀態值。第2行和第4行將包含在計數中。第3行被排除,因爲它有不正確的type
。由於狀態不正確,第5行被排除。第6行被排除,因爲狀態和類型都不正確。排除第1行,因爲它在日期範圍之外。第7行也被排除,因爲還有一行(第1行)與狀態和類型標準相匹配,並且具有相同的recordId
,該行比日期範圍的開始時間更早。第8行被排除,因爲第8行和第2行具有相同的recordId
並符合標準,但我們只計算範圍內兩個最舊的記錄。
換句話說,我想只計算給定recordId的條目第一次出現在表中並且在目標日期範圍內。
我們已經想出了以下內容:
WITH data (recordId, id) AS (
SELECT a.recordId, MIN(a.id)
FROM audit a
WHERE a.status in ('A','B','C')
AND type = 'type1'
GROUP BY a.recordId
)
SELECT r.source, COUNT(*)
FROM data d
JOIN audit a ON d.id = a.id
LEFT JOIN related r ON a.relatedId = r.id
WHERE a.mdate >= '2013-04-04 00:00:00.000'
and a.mdate < '2013-04-05 00:00:00.000'
GROUP BY r.source
這將MSSQL Server 2008上運行,目前依賴於一個事實,即審計表ID是自動生成的。由於id是在插入記錄時生成的,並且mdate也是插入時間戳,並且記錄一旦插入就不會更新,所以我認爲這是正確的。該查詢似乎給出了有限的一組測試數據的正確輸出,但我希望得到第二個意見。
- 此查詢是否正常?
- 其性能可以提高嗎?
計算表格表達式中的日期範圍可能會提高性能。 –
好點。將'AND a.mdate <'2013-04-05 00:00:00.000''添加到計算表中將有助於限制它返回的記錄數。 –
爲了提高查詢性能,請考慮索引。在WHERE Clause Fields,Join Fields上使用索引,然後再次測試性能。 – 2013-06-26 11:58:25