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/1/angularjs/24.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 - Fatal编程技术网

Sql 返回每列的最新记录

Sql 返回每列的最新记录,sql,sql-server,Sql,Sql Server,样本表 +--------+------------+------------------+-------------+-------------+ | FileID | Date | Activity | Assigned_By | Responsible | +--------+------------+------------------+-------------+-------------+ | 123 | 2016/01/01 | Work in p

样本表

+--------+------------+------------------+-------------+-------------+
| FileID |    Date    |     Activity     | Assigned_By | Responsible |
+--------+------------+------------------+-------------+-------------+
|    123 | 2016/01/01 | Work in progress | Foo1        | Bob         | 
|    234 | 2016/01/01 | Work in progress | Foo2        | Smith       | 
|    123 | 2016/01/02 | Escalated        | NULL        | NULL        | 
|    123 | 2016/01/03 | Need reassign    | NULL        | NULL        | 
|    123 | 2016/01/03 | Reassigned       | Foo2        | John        | 
|    234 | 2016/01/03 | Completed        | NULL        | NULL        |
|    123 | 2016/01/04 | Completed        | NULL        | NULL        |
+--------+------------+------------------+-------------+-------------+
我的问题是:

SELECT FileID,
       Date,
       Activity,
       Assigned_By,
       Responsible
FROM (
      SELECT fooTable.*, ROW_NUMBER() OVER (PARTITION BY FileID ORDER BY Date DESC) AS Separator
     ) fooTable
INNER JOIN randomTable ON fooTable.FileID = randomTable.ID
WHERE fooTable.Separator = 1;
返回:

+--------+------------+-----------+-------------+-------------+
| FileID |    Date    | Activity  | Assigned By | Responsible |
+--------+------------+-----------+-------------+-------------+
|    234 | 2016/01/03 | Completed | NULL        | NULL        |
|    123 | 2016/01/04 | Completed | NULL        | NULL        |
+--------+------------+-----------+-------------+-------------+
所需结果-返回每一行的每个唯一FileID的最新列记录和最新日期:

+--------+------------+-----------+-------------+-------------+
| FileID |    Date    | Activity  | Assigned By | Responsible |
+--------+------------+-----------+-------------+-------------+
|    234 | 2016/01/03 | Completed | Foo2        | John        |
|    123 | 2016/01/04 | Completed | Foo1        | Bob         |
+--------+------------+-----------+-------------+-------------+
我有点理解为什么查询不起作用,因为它只返回最新的行(按行号分配1),因此我将根据降序日期接收该唯一FileID的第一行记录。但我不知道如何修复它


编辑:我意识到的另一点是MAX()将不适用于Assigned By和Responsible(我认为),因为它将返回更大的字母名称…

您可以使用联接,也可以使用FIRST\u值,如下所示:

SELECT 
  FileID,
  FIRST_VALUE(Date) OVER (PARTITION BY FileID ORDER BY Date DESC ROWS  BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS Date,
  FIRST_VALUE(Activity) OVER (PARTITION BY FileID ORDER BY CASE WHEN Activity IS NULL THEN 0 ELSE 1 END DESC, Date DESC ROWS  BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS Activity,
  FIRST_VALUE(Assigned_By) OVER (PARTITION BY FileID ORDER BY CASE WHEN Assigned_By IS NULL THEN 0 ELSE 1 END DESC, Date DESC ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS Assigned_By,
  FIRST_VALUE(Responsible) OVER (PARTITION BY FileID ORDER BY CASE WHEN Responsible IS NULL THEN 0 ELSE 1 END DESC, Date DESC ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS Responsible
FROM fooTable
INNER JOIN randomTable ON fooTable.FileID = randomTable.ID
WHERE fooTable.Separator = 1;     

您可以使用条件聚合执行所需操作:

WITH t AS (
      SELECT FileID, Date, Activity, Assigned_By, Responsible
      FROM fooTable INNER JOIN 
           randomTable
           ON fooTable.FileID = randomTable.ID
     )
SELECT FileID, MAX(Date) as date,
       MAX(CASE WHEN seqnum = 1 THEN Activity END) as Activity,
       MAX(CASE WHEN seqnum_nonnull = 1 THEN Assigned_By END) as Assigned_By,
       MAX(CASE WHEN seqnum_nonnull = 1 THEN Responsible END) as Responsible
FROM (SELECT t.*,
             ROW_NUMBER() OVER (PARTITION BY FileID ORDER BY Date DESC) AS seqnum,
             ROW_NUMBER() OVER (PARTITION BY FileID
                                ORDER BY (CASE WHEN AssignedBy IS NOT NULL THEN 1 ELSE 2 END), Date DESC
                               ) AS seqnum_notnull
      FROM t
     ) t
GROUP BY FileID;

对于每个可为空的列,您需要额外查询该表一次。您可以对FileID、Date、Activity执行当前查询(假设Activity不可为null),然后将另一个查询留给Assigned By和Responsible。附加查询将添加where子句“where{column}不为NULL”。这如何防止
NULL
值?它似乎相当于OP的代码。@GordonLinoff——在db2中,默认情况是第一个_值不包含null值——我没有在sql server中测试过这一点,但我是在做这个假设。@GordonLinoff——是的,sql server不允许您忽略像db2和oracle这样的null——必须在另一个order by子句中添加它才能作为我的编辑--感谢您找到问题。@Hogan这是更新后的一个很好的答案,唯一的问题是额外的列会使查询变得有点混乱,因此Gordon的条件聚合的使用更干净。不过,我还是非常感谢你。@Simon——不客气。这是一个有用的答案,可以知道您是否需要一些列首先基于日期,而其他列首先基于不同的顺序。取决于许多其他因素,它可能比其他解决方案更快。Linoff,如果操纵数据是世界饥饿,你会解决它的。这非常有效,非常感谢你。