簡體   English   中英

SQL查詢幫助(加入視圖?)

[英]Help with SQL query (Joining views?)

我有一張有欄的桌子

索引,日期

其中一個索引可能有多個日期,而我的目標是:選擇一個看起來像這樣的列表

索引,最小日期,最大日期

其中每個索引僅列出一次,而MinDate(MaxDate)代表該索引在整個表格中出現的最早(最新)日期。 這很容易,但是讓我們限制此列表僅顯示給定日期范圍內的索引。

到目前為止,我有以下內容:

SELECT 
    Index,
    MIN([Date]),
    MAX([Date])
FROM myTable
WHERE
    Index IN
    (SELECT Index From myTable WHERE [Date] BETWEEN '1/1/2000' AND '12/31/2000')
GROUP BY Index
ORDER BY Index ASC

這太慢了。 有什么辦法可以加快速度嗎? [我正在運行SQL Server2000。]

謝謝!

編輯:為清楚起見。

我建議使用派生表方法。 像這樣:

SELECT 
     myTable.Index,
     MIN(myTable.[Date]),
     MAX(myTable.[Date])
FROM myTable
     Inner Join (
       SELECT Index 
       From myTable 
       WHERE [Date] BETWEEN '1/1/2000' AND '12/31/2000') As AliasName
       On myTable.Index = AliasName.Index
GROUP BY myTable.Index
ORDER BY myTable.Index ASC

編輯:經過進一步審查,還有另一種方法可以創建此查詢。 以下查詢可能更快,更慢或在相同的時間內執行。 當然,這取決於表的索引方式。

Select [Index],
       Min([Date]),
       Max([Date])
From   myTable
Group By [Index]
Having Sum(Case When [Date] Between '1/1/2000' And '12/31/2000' Then 1 Else 0 End) > 0

在最佳情況下,此查詢將導致索引掃描(而不是查找)過濾掉您不想顯示的行。 我鼓勵您同時運行兩個查詢,並選擇最快的速度執行。

我不是SQL Server專家,但是如果您可以像這樣進行子選擇,則可能會更快。

SELECT Index,
  (SELECT MIN([Date] FROM myTable WHERE Index = m.Index),
  (SELECT MAX([Date] FROM myTable WHERE Index = m.Index)
From myTable m 
WHERE [Date] BETWEEN '1/1/2000' AND '12/31/2000'

傑克

我認為您可能需要在此問題上采用其他POV。

與它涵蓋的數據范圍(可能是多年)相比,“ **Index, Min(Date), Max(Date)**所選擇的分組在一天的過程中不會發生巨大變化。

因此,一種選擇是根據主表中的數據創建一個匯總表...例如

   SELECT 
       Index, 
       Min(Date) as MinDate, 
       Max(Date) as MaxDate
   INTO 
      MySummaryTable
   FROM 
      MyOriginalTable
   GROUP BY
      Index

可以刪除該表並通過sql作業在半常規(每天)的基礎上重新創建。 同樣,我會在其id列上添加索引。

然后,當您需要運行時,您可以每天查詢一次,

SELECT 
   summary.Index,
   summary.MinDate,
   summary.MaxDate
FROM
   MyOriginalTable mot
   INNER JOIN MySummaryTable summary
      ON mot.Index = summary.Index  --THIS IS WHERE YOUR CLUSTERED INDEX WILL PAY OFF
WHERE
   mot.Date BETWEEN '2000-01-01' AND '2000-12-31' --THIS IS WHERE A SECOND NC INDEX WILL PAY OFF

這應該在兩個表掃描中完成。

SELECT
     Index,
    MIN([Date]),
    MAX([Date])
FROM myTable
WHERE
    Index IN
    (SELECT Index From myTable WHERE [Date] BETWEEN '1/1/2000' AND '12/31/2000')
GROUP BY Index
ORDER BY Index ASC
OPTION (MERGE JOIN)

這是另一個查詢。 該查詢得到的結果與最初要求的結果不同 這將獲取所有日期范圍與關注期間重疊的索引(即使該索引在關注期間沒有任何實際活動)。

SELECT
    Index,
    MIN([Date]),
    MAX([Date])
FROM myTable
GROUP BY Index
HAVING MIN([Date]) < '2001-01-01' AND MAX([Date]) >= '2000-01-01')
ORDER BY Index ASC

因此,即使3在2000年中沒有數據,這也將返回。

3、1998年1月1日,2005年1月1日

在日期列上放置聚簇索引將大大加快此查詢的速度,但是顯然,它可能會減慢表上其他當前快速運行的查詢的速度。

您的解釋不是很清楚:

其中每個索引僅列出一次,而MinDate(MaxDate)代表整個表格中出現的最早(最新)日期。

在這種情況下,您應該返回兩個結果集或存儲答案,例如:

DECLARE @MaxDate datetime, @MinDate datetime
SELECT
    @MinDate = MIN([Date]),
    @MaxDate = MAX([Date])
FROM myTable
--
SELECT
    [Index],
    @MinDate,
    @MaxDate
FROM myTable
WHERE [Date] BETWEEN '1/1/2000' AND '12/31/2000'

如果您想知道整個表以及[索引]的最小/最大,請結合以下代碼嘗試以下操作:

SELECT
    [Index],
    MIN([Date]) AS IndexMinDate,
    MAX([Date]) AS IndexMaxDate,
    @MinDate AS TableMinDate,
    @MaxDate AS TableMaxDate
FROM myTable
WHERE [Date] BETWEEN '1/1/2000' AND '12/31/2000'
GROUP BY [Index]
ORDER BY [Index] ASC

如果可能的話,還要考慮對列進行索引和查詢計划。 祝好運。

EXISTS運算符可能比子查詢快:

SELECT
     t1.Index,
     MIN(t1.[Date]),
     MAX(t1.[Date])
FROM
     myTable t1
WHERE
     EXISTS (SELECT * FROM myTable t2 WHERE t2.Index = t1.Index AND t2.[Date] >= '1/1/2000' AND t2.[Date] < '1/1/2001')
 GROUP BY
      t1.Index

我想這將取決於表的大小和索引。 我也喜歡G Mastros HAVING子句解決方案。

另一個重要說明...如果您的日期實際上是DATETIME,並且任何日期(現在或將來)中都有時間成分,則如果索引的日期為2000年12月31日,則可能會錯過某些結果除了午夜以外的任何時間。 只是要記住一點。 您也可以使用YEAR([Date])= 2000(假設此處為MS SQL Server)。 我不知道如果您這樣做,數據庫是否足夠聰明,可以在日期列上使用索引。

編輯:由於評論,添加了GROUP BY並更改了日期邏輯

您不需要where子句中的子選擇。 另外,您可以將索引添加到日期列。 表中有幾行?

SELECT
    [INDEX],
    MIN ( [Date] ),
    MAX ( [Date] )
FROM
    myTable
WHERE 
    [Date] Between '1/1/2000' And '12/31/2000'
GROUP BY
    [Index]
ORDER BY
    [INDEX] ASC

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM