Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL查询帮助(加入视图?)_Sql - Fatal编程技术网

SQL查询帮助(加入视图?)

SQL查询帮助(加入视图?),sql,Sql,我有一张有列的桌子 索引、日期 其中一个索引可能有多个日期,我的目标如下:选择一个如下所示的列表 索引,MinDate,MaxDate 其中每个索引只列出一次,MinDate MaxDate表示该索引在整个表中出现的最早的最新日期。这很简单,但接下来让我们限制此列表仅显示在给定日期范围内的索引 到目前为止,我有以下几点: SELECT Index, MIN([Date]), MAX([Date]) FROM myTable WHERE Index IN

我有一张有列的桌子

索引、日期

其中一个索引可能有多个日期,我的目标如下:选择一个如下所示的列表

索引,MinDate,MaxDate

其中每个索引只列出一次,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。]

谢谢


编辑:为清晰起见。

您不需要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

在日期列上放置聚集索引将大大加快此查询的速度,但显然它可能会减慢表上其他当前快速运行的查询的速度。

我不是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 
     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
在最佳情况下,此查询将导致索引扫描而不是搜索,以筛选出不希望显示的行。我鼓励您运行这两个查询,并选择执行速度最快的查询。

Jake

我认为你可能需要对这个问题采取不同的观点

与其可能涵盖多年的数据范围相比,所选**指数、MinDate、MaxDate**的分组不会在一天内发生剧烈变化

因此,一种选择是根据主表中的数据创建一个汇总表。。。e、 g

   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

你的解释不是很清楚:

其中每个索引只列出一次,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马斯特罗斯的从句解决方案

另一个重要的提示。。。如果您的日期实际上是日期时间,并且您的任何日期(无论是现在还是将来)中都有时间成分,那么如果索引的日期为2000年12月31日,且时间不在午夜,则可能会错过一些结果。只是要记住一些事情。您也可以使用YEAR[Date]=2000,假设此处使用MS SQL Server。如果你这样做的话,我不知道DB是否会聪明到在date列上使用索引


编辑:由于注释,添加了分组依据和更改了日期逻辑。这应该在两次表扫描中完成

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-012005-01-01-01

您是否在日期列上创建了索引?抱歉,这不起作用,因为这将MinDate和MaxDate作为给定范围的极值,但我们需要它们用于整个表格。您需要整个表格的最大值和最小值,但只需要在2000年有记录的项目?日期逻辑上的观点很好。是-YEARDate将阻止索引的使用。而是使用“2000-01-01”,第一个查询应作为原始查询执行。第二个查询可能是1表扫描非常好。预计的执行计划将得到确认。到目前为止,这是在不创建新表的情况下最快的执行计划。