【问题标题】:SQL Server, complex querySQL Server,复杂查询
【发布时间】:2017-09-05 10:07:16
【问题描述】:

我有一个通过导入 XML 文件填充的 Azure SQL 数据库表。

文件的顺序是随机的,所以我可以得到这样的东西:

ID  | Name  | DateFile | IsCorrection | Period | Other data
1   | Mr. A | March, 1 | false        | 3      | Foo
20  | Mr. A | March, 1 | true         | 2      | Foo
13  | Mr. A | Apr, 3   | true         | 2      | Foo
4   | Mr. B | Feb, 1   | false        | 2      | Foo

此表与另一个表连接,该表也与第三个表连接。

我需要根据 Period、DateFile 和 Correction 为拥有最新数据的人获取这 3 个表的连接。

在我上面的例子中,Id=1 是周期 3 的原始数据,我需要这条记录。 但在同一个文件中也对第 2 期(Id=20)进行了更正,在 4 月的文件中,数据再次更正了(Id=13)。

所以对于第 3 期,我需要 Id=1,对于第 2 期,我需要 Id=13,因为它有最后更正的数据,我需要 Id=4,因为它是另一个人。

我想在视图中执行此操作,但使用存储过程不会有问题。

我不知道如何解决这个问题。任何指针将不胜感激。

编辑: 我的数据模型当然比这个示例复杂得多。 DateFile 和 Period 是表中的 DateTime 类型。实际上 Period 是两个 DateTime 列:StartPeriod 和 EndPeriod。

【问题讨论】:

  • edit您的问题将示例数据包含为 DDL+DML(创建表并插入语句)和所需的结果。
  • 您的日期字段真的只是月、日格式,而不是真正的日期(日期/时间)吗? 2016 年第 2 期和 2017 年第 2 期之间的含义是什么?
  • 我更新了我的帖子。希望现在更清楚了。

标签: sql sql-server azure select group-by


【解决方案1】:

看看您的数据,我相信我们可以忽略 IsCorrection 列,而只为每个用户/期间选择最新的列。 让我们从排列最新的行开始:

SELECT  ROW_NUMBER() OVER (PARTITION BY Period, Name ORDER by DateFile DESC), *

然后从这个结果中选择所有行号为 1 的:

;with numberedRows as (
  SELECT  ROW_NUMBER() OVER (PARTITION BY Period, Name ORDER by DateFile DESC) as rowIndex, *
)

select * from numberedRows where rowIndex=1

PARTITION BY 告诉 ROW_NUMBER() 在遇到 Period 和 Name 列的变化时重置计数器。 ORDER BY 告诉 ROW_NUMBER() 我们希望最新的行是第 1 行,然后是旧的帖子。我们只需要最新的一行。

WITH 声明了一个“公用表表达式”,它是一种子查询或临时表。

不知道你的确切数据,我可能会向你推荐一些错误的东西,但你应该能够将你的最后一个查询与其他表结合起来以获得你想要的结果。

类似:

;with numberedRows as (
  SELECT  ROW_NUMBER() OVER (PARTITION BY Period, Name ORDER by DateFile DESC) as rowIndex, *
)

select * from numberedRows a 
JOIN periods b on b.empId = a.Id 
JOIN msg c on b.msgId = c.Id
where a.rowIndex=1

【讨论】:

  • 谢谢,亨德里克。这PARTITIONWITH 的东西对我来说是新的。我正在赶上我的阅读。我了解PARTITION 部分,但还不是最后两个步骤。如果我的查询是SELECT a.Name, b.Period, c.DateFile FROM emp a JOIN periods b on b.empId = a.Id JOIN msg c on b.msgId = c.Id 如何将您的代码合并到其中?这个查询又被简化了。
  • 感谢它现在正在工作。我会把你的帖子标记为答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-03
相关资源
最近更新 更多