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,我试图一次从一张桌子上得到两行。最短日期时间(今天-7)为上周,最晚日期时间(今天)为上周。 我的桌子: |id |dataIn |dataOut|date |MachineId | -----+-------+-------+-----------------------+-------------------------------------+ |1 |5006 |58 |2011-

我试图一次从一张桌子上得到两行。最短日期时间(今天-7)为上周,最晚日期时间(今天)为上周。
我的桌子:

|id  |dataIn |dataOut|date                   |MachineId                            |
-----+-------+-------+-----------------------+-------------------------------------+
|1   |5006   |58     |2011-10-25 09:03:17.000|7B788EE88E-6527-4CB4-AA4D-01B7F4048559  
|2   |1200   |130    |2011-10-26 12:45:43.000|7B788EE88E-6527-4CB4-AA4D-01B7F4048559 
        ...  
|124 |1350   |480    |2011-10-29 13:29:04.000|7B788EE88E-6527-4CB4-AA4D-01B7F4048559  
|125 |8005   |560    |2011-10-31 21:18:35.000|7B788EE88E-6527-4CB4-AA4D-01B7F4048559  
我可以使用以下选项选择上周的数据:

选择
dbo.myDatabase.Date为[Date],dbo.myDatabase.dataIn为[in],
dbo.myDatabase.dataOut作为[out]
从…起
dbo.myDatabase在哪里
Date>=dateadd(day,datediff(day,0,GetDate())-7,0)
及
dbo.myDatabase.MachineId='7B788EE88E-6527-4CB4-AA4D-01B7F4048559'
但我只想要第1行和第125行,因为这些是我计算时使用的行。 所以我的问题是:
如何从上一次查询的结果中选择两行(最小和最大日期)?

您可以使用:

select * from dbo.myDatabase 
where 
    ([Date] = (select max([Date]) from /* your query */ ) or 
    [Date] = (select min([Date]) from /* your query */ ))
    and MachineId = '7B788EE88E-6527-4CB4-AA4D-01B7F4048559' -- or any other id

编辑:由于两台机器完全可能具有相同的
日期
值,因此应更新查询,以便在
where
子句中也包含
机器ID
过滤器。我更新了查询以显示这一点。

如果您有多个日期相同的行,此查询将确保最小/最大值只返回一行(仅适用于Sql 2005+)


通过阅读注释,以及每台机器执行其自己的插入,插入不会插入自动增量列的值,因为这是由引擎处理的。因此,除非机器正在更改其日期/时间,否则自动增量ID与每台机器的日期/时间存在直接关联。因此,也就是说,我创建的示例获得了每个机器的最小和最大ID,其中日期/时间是合格的,它将为所讨论的范围生成最终的第一个和最后一个ID。然后您可以获得特定的ID记录

所以,如果你有3台机器,它们在同一时间进行插入,它们各自的ID将以不同的方式生成

|id  |date                   |MachineId                            |
-----+-------+-------+-----------------
|1   |2011-10-25 09:03:17.000| A
|2   |2011-10-25 09:03:17.000| B
|3   |2011-10-25 09:03:17.000| C

|4   |2011-10-26 12:45:43.000| B
|5   |2011-10-26 12:45:43.000| A
|6   |2011-10-26 12:45:43.000| C

        ...  

|124 |2011-10-29 13:29:04.000| C
|125 |2011-10-29 13:29:04.000| A
|126 |2011-10-29 13:29:04.000| B

|127 |2011-10-31 21:18:35.000| C
|128 |2011-10-31 21:18:35.000| B
|129 |2011-10-31 21:18:35.000| A

The first and last IDs per respective machine would become
Machine First ID   Last ID
A         1         129
B         2         128
C         3         127
内部预查询只执行一次(针对特定机器),因此您将获得与每个机器日期/时间段的第一个/最后一个实例关联的ID。然后将其连接回表中,以获得ID匹配的实际数据

select 
      D2.*
   FROM
      ( SELECT 
              min( D1.ID ) MinDateID,
              max( D1.ID ) MaxDateID
           from
              dbo.myDatabase D1
           where
                  D1.MachineId = '7B788EE88E-6527-4CB4-AA4D-01B7F4048559' 
              AND D1.Date >=dateadd(day,datediff(day,0,GetDate())- 7,0)
      ) PreQuery
      JOIN dbo.MyDatabase D2
         on PreQuery.MinDateID = D2.ID
         OR PreQuery.MaxDateID = D2.ID

可能有多行具有最小或最大日期。那么,您想做什么?日期/时间戳是否与明显的自动增量ID列直接相关?@TimRogers No.当发生更改时,每台机器都会插入一行带有日期时间的数据,因此它是唯一的/machine@DRapp没有相关性。我只是想得到一周的总输入和总输出,这是过去7天内第一行和最后一行的数据输入/输出之间的差异。根据OP对这个问题的评论,
ID
s与最小和最大日期不相关。不过,只需对“最小日期”和“最大日期”进行一点更改,这也可以使用。@user798612,请参阅“每个示例数据上下文的答案中的说明”请参阅“我的答案中的说明…”。。。完全依赖于日期相等的查询将起作用,但也将返回与给定日期匹配的任何内容的多条记录,即使是在发送数据的不同计算机之间。@DRapp我明白您的观点,即返回与日期匹配的所有内容,即使是在不同的
MachineId
之间。我更新了我的答案来解决这个问题。如果您有组,您会怎么做?这意味着每个组都有一个最大(日期)…+1,但您可能会在行编号中添加另一个字段(例如,
按日期排序ASC,dbo.Mydatabase(id)ASC
)使分片更具确定性。如果窗口聚合函数应用于整个行集,您只需省略
PARTITION BY
子句(例如:
MIN(row)OVER()作为lower_row
)。@Andriy M-通过ommitting PARTITION BY(选择NULL)是否有可能提高性能?就我个人而言,我觉得使用它更具可读性,但那可能只是我自己@Davin:很难说,部分原因是我以前可能从未遇到过
partitionby(selectnull)
。不过,我不希望有什么不同。
select 
      D2.*
   FROM
      ( SELECT 
              min( D1.ID ) MinDateID,
              max( D1.ID ) MaxDateID
           from
              dbo.myDatabase D1
           where
                  D1.MachineId = '7B788EE88E-6527-4CB4-AA4D-01B7F4048559' 
              AND D1.Date >=dateadd(day,datediff(day,0,GetDate())- 7,0)
      ) PreQuery
      JOIN dbo.MyDatabase D2
         on PreQuery.MinDateID = D2.ID
         OR PreQuery.MaxDateID = D2.ID