English 中文(简体)
需要SQL查询帮助(连接视图)?
原标题:
  • 时间:2008-10-31 17:08:55
  •  标签:

我有一张有列的表

索引,日期

索引可能有多个日期,我想实现的目标是选择一个类似于的列表

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

每个指标仅列出一次,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 Server 2000]。

谢谢!

编辑:为了清晰明了。

最佳回答

我建议采用派生表方法。像这样:

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 

杰克,

我认为你需要从不同的角度看待这个问题。

所选的分组**指数,最小日期,最大日期**一天内不会与其所覆盖的数据范围(可能多年)相比发生剧烈变化。

因此,一种选择是基于主表中的数据创建摘要表格...例如。

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

This table could be dropped and recreated on a semi-regular (daily) base via a sql job. Equally I d stick an index on the id column of it.

然后当你需要运行每日查询时,

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年01月01日,2005年01月01日

在日期列上创建一个聚簇索引可以大大加快此查询的速度,但显然可能会放慢表上其他当前运行速度快的查询。

你的解释不是很清楚。

每个索引只列出一次,并且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 

如果您想知道整个表格的最小/最大值以及[Index]的值,则请尝试结合先前代码使用以下代码:

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,并且任何一个日期中都存在时间组件(无论是现在还是将来),如果索引具有除午夜以外的任何时间的日期,则可能会错过一些结果。请记住这一点。您可以选择使用YEAR([日期])= 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




相关问题
热门标签