Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/83.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.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_Sql Server_Tsql_Group By - Fatal编程技术网

Sql 按行分组查找最小值

Sql 按行分组查找最小值,sql,sql-server,tsql,group-by,Sql,Sql Server,Tsql,Group By,在SQL空间(特别是T-SQL、SQL Server 2008)中,给定以下值列表: Status Date ------ ----------------------- ACT 2012-01-07 11:51:06.060 ACT 2012-01-07 11:51:07.920 ACT 2012-01-08 04:13:29.140 NOS 2012-01-09 04:29:16.873 ACT

在SQL空间(特别是T-SQL、SQL Server 2008)中,给定以下值列表:

    Status  Date
    ------  -----------------------
    ACT     2012-01-07 11:51:06.060
    ACT     2012-01-07 11:51:07.920
    ACT     2012-01-08 04:13:29.140
    NOS     2012-01-09 04:29:16.873
    ACT     2012-01-21 12:39:37.607         <-- THIS
    ACT     2012-01-21 12:40:03.840
    ACT     2012-05-02 16:27:17.370
    GRAD    2012-05-19 13:30:02.503
    GRAD    2013-09-03 22:58:48.750
此特定对象的状态从ACT开始,然后更改为NOS,然后返回ACT,再更改为GRAD

从状态为'ACT'的最新记录“组”中获取最短日期的最佳方法是什么

SELECT [Status], MIN([Date])
FROM Table_Name
WHERE [Status] = (SELECT [Status]
                  FROM Table_Name
                  WHERE [Date] = (SELECT MAX([Date])
                                  FROM Table_Name)
                  )
GROUP BY  [Status]
试试这里


请尝试此处

以下是一个查询,通过识别学生状态相同的组,然后使用简单的聚合:

select top 1 StudentStatus, min(WhenLastChanged) as WhenLastChanged
from (SELECT StudentStatus, WhenLastChanged,
             (row_number() over (order by "date") -
              row_number() over (partition by studentstatus order by "date)
            ) as grp
      FROM Account_History
      WHERE AccountNumber = '1234'
    ) t
where StudentStatus = 'ACT'
group by StudentStatus, grp
order by WhenLastChanged desc;
row\u number()
函数根据
日期在一组行中分配序号。对于您的数据,两个
行编号()
和它们的区别是:

Status  Date
------  -----------------------
ACT     2012-01-07 11:51:06.060    1      1      0
ACT     2012-01-07 11:51:07.920    2      2      0
ACT     2012-01-08 04:13:29.140    3      3      0
NOS     2012-01-09 04:29:16.873    4      1      3
ACT     2012-01-21 12:39:37.607    5      4      1
ACT     2012-01-21 12:40:03.840    6      5      1
ACT     2012-05-02 16:27:17.370    7      6      1
GRAD    2012-05-19 13:30:02.503    8      1      7
GRAD    2013-09-03 22:58:48.750    9      2      7
请注意,对于具有相同状态的行,最后一行是常量

聚合将这些数据集合在一起,并选择第一个日期(
min(date)
)中最新的(
top 1…order by date desc

编辑:

对于多个帐号,查询很容易调整。我可能应该这样开始写,除非最后的选择比较棘手。此操作的结果具有每个状态和帐户的日期:

select StudentStatus, min(WhenLastChanged) as WhenLastChanged
from (SELECT StudentStatus, WhenLastChanged, AccountNumber
             (row_number() over (partition by AccountNumber order by WhenLastChanged) -
              row_number() over (partition by AccountNumber, studentstatus order by WhenLastChanged)
            ) as grp
      FROM Account_History
    ) t
where StudentStatus = 'ACT'
group by AccountNumber, StudentStatus, grp
order by WhenLastChanged desc;
但是你不可能很容易地得到每个帐户的最后一个。另一级子查询:

select AccountNumber, StudentStatus, WhenLastChanged
from (select AccountNumber, StudentStatus, min(WhenLastChanged) as WhenLastChanged,
             row_number() over (partition by AccountNumber, StudentStatus order by min(WhenLastChanged) desc
                               ) as seqnum
      from (SELECT AccountNumber, StudentStatus, WhenLastChanged,
                   (row_number() over (partition by AccountNumber order by WhenLastChanged) -
                    row_number() over (partition by AccountNumber, studentstatus order by WhenLastChanged)
                  ) as grp
            FROM Account_History
          ) t
      where StudentStatus = 'ACT'
      group by AccountNumber, StudentStatus, grp
     ) t
where seqnum = 1;

这将使用聚合以及窗口函数
row\u number()
。这是将序号分配给组(聚合后),每个帐户的最后日期的值为1(
orderbymin(WhenLastChanged)desc
)。最外面的
选择
,然后只为每个帐户选择该行。

下面是一个查询,通过识别学生状态相同的组,然后使用简单的聚合来实现这一点:

select top 1 StudentStatus, min(WhenLastChanged) as WhenLastChanged
from (SELECT StudentStatus, WhenLastChanged,
             (row_number() over (order by "date") -
              row_number() over (partition by studentstatus order by "date)
            ) as grp
      FROM Account_History
      WHERE AccountNumber = '1234'
    ) t
where StudentStatus = 'ACT'
group by StudentStatus, grp
order by WhenLastChanged desc;
row\u number()
函数根据
日期在一组行中分配序号。对于您的数据,两个
行编号()
和它们的区别是:

Status  Date
------  -----------------------
ACT     2012-01-07 11:51:06.060    1      1      0
ACT     2012-01-07 11:51:07.920    2      2      0
ACT     2012-01-08 04:13:29.140    3      3      0
NOS     2012-01-09 04:29:16.873    4      1      3
ACT     2012-01-21 12:39:37.607    5      4      1
ACT     2012-01-21 12:40:03.840    6      5      1
ACT     2012-05-02 16:27:17.370    7      6      1
GRAD    2012-05-19 13:30:02.503    8      1      7
GRAD    2013-09-03 22:58:48.750    9      2      7
请注意,对于具有相同状态的行,最后一行是常量

聚合将这些数据集合在一起,并选择第一个日期(
min(date)
)中最新的(
top 1…order by date desc

编辑:

对于多个帐号,查询很容易调整。我可能应该这样开始写,除非最后的选择比较棘手。此操作的结果具有每个状态和帐户的日期:

select StudentStatus, min(WhenLastChanged) as WhenLastChanged
from (SELECT StudentStatus, WhenLastChanged, AccountNumber
             (row_number() over (partition by AccountNumber order by WhenLastChanged) -
              row_number() over (partition by AccountNumber, studentstatus order by WhenLastChanged)
            ) as grp
      FROM Account_History
    ) t
where StudentStatus = 'ACT'
group by AccountNumber, StudentStatus, grp
order by WhenLastChanged desc;
但是你不可能很容易地得到每个帐户的最后一个。另一级子查询:

select AccountNumber, StudentStatus, WhenLastChanged
from (select AccountNumber, StudentStatus, min(WhenLastChanged) as WhenLastChanged,
             row_number() over (partition by AccountNumber, StudentStatus order by min(WhenLastChanged) desc
                               ) as seqnum
      from (SELECT AccountNumber, StudentStatus, WhenLastChanged,
                   (row_number() over (partition by AccountNumber order by WhenLastChanged) -
                    row_number() over (partition by AccountNumber, studentstatus order by WhenLastChanged)
                  ) as grp
            FROM Account_History
          ) t
      where StudentStatus = 'ACT'
      group by AccountNumber, StudentStatus, grp
     ) t
where seqnum = 1;
这将使用聚合以及窗口函数
row\u number()
。这是将序号分配给组(聚合后),每个帐户的最后日期的值为1(
orderbymin(WhenLastChanged)desc
)。最外层的
选择
,然后为每个帐户选择该行

霍根:基本上,是的。我只想知道飞机起飞的日期/时间 帐户最后更改为ACT。以上各点之后的记录 这是额外的

我们可以查找第一次状态更改并从中选择act(和max),而不只是查找act

所以。。。每次状态更改时:

with rownumb as
(
   select *, row_number() OVER (order by date asc) as rn
)
select status, date
from rownumb A
join rownumb B on A.rn = B.rn-1
where a.status != b.status
现在查找act项目的最大值

with rownumb as
(
   select *, row_number() OVER (order by date asc) as rn
), statuschange as
(
  select status, date
  from rownumb A
  join rownumb B on A.rn = B.rn-1
  where a.status != b.status
)
select max(date) 
from satuschange 
where status='Act'
霍根:基本上,是的。我只想知道飞机起飞的日期/时间 帐户最后更改为ACT。以上各点之后的记录 这是额外的

我们可以查找第一次状态更改并从中选择act(和max),而不只是查找act

所以。。。每次状态更改时:

with rownumb as
(
   select *, row_number() OVER (order by date asc) as rn
)
select status, date
from rownumb A
join rownumb B on A.rn = B.rn-1
where a.status != b.status
现在查找act项目的最大值

with rownumb as
(
   select *, row_number() OVER (order by date asc) as rn
), statuschange as
(
  select status, date
  from rownumb A
  join rownumb B on A.rn = B.rn-1
  where a.status != b.status
)
select max(date) 
from satuschange 
where status='Act'


这里缺少一些组。如果按“最短日期”OP表示最早,这就是您需要的want@Hogan少了什么?看起来不错me@MBarnett如前所述,这将得到他毕业时的最短日期,而不是毕业时的最短日期act@M.Ali我不是问/修改问题的人,但是的,要求可能已经改变。这里缺少一些组。如果在“最短日期”前OP表示最早,这就是你想要的want@Hogan少了什么?看起来不错me@MBarnett如前所述,这将得到他毕业时的最短日期,而不是毕业时的最短日期act@M.Ali我不是问/修改这个问题的人,但是的,要求可能已经改变了。我不明白,是什么促使人们需要行动——投入?霍根:基本上,是的。我只想知道账户最后更改为ACT的日期/时间。上面标记这一点后的记录只是额外的。我不明白,是什么驱动了ACT——输入的需要?霍根:基本上,是的。我只想知道账户最后更改为ACT的日期/时间。上面标记这一点后的记录只是额外的。在看到您的编辑(添加WHERE子句)之前,我调整了您的查询,它对我非常有效。我很想更好地理解这个答案,所以我将对此进行研究。为了提高效率,如果我想通过加入一个具有多个帐号的表来实现最后的多个更改,我应该如何实现这一点?换句话说,我有一个有3个帐号的表,我想知道每个帐号的相同信息。(请原谅,如果问这个问题的地方不对,请告诉我,我很乐意搬走。)@TSFroggy-看看我的答案,使用CTEs可能更容易摸索。我不确定哪一个会更快。霍根,对不起,我无法让你的查询运行。@Gordon我希望我能投赞成票,但正如你所看到的,我是一个长期潜伏者,很少有时间。感谢您提供了非常详细和全面的答案。@Gordon对您的最终查询进行了一些编辑以使其运行。在看到您的编辑(添加WHERE子句)之前,我对您的查询进行了调整,它非常适合我。我很想更好地理解这个答案,所以我将对此进行研究。为了提高效率,如果我想通过加入一个具有多个帐号的表来实现最后的多个更改,我应该如何实现这一点?换句话说,我有一个有3个帐号的表,我想知道相同的帐号