【问题标题】:Querying single table and merge result for same DateTime查询单个表并合并相同日期时间的结果
【发布时间】:2018-09-13 07:03:47
【问题描述】:

我有一个表,我在其中插入与 id 相关的值,这些值会随着时间而变化。

示例:

|身份证 |时间戳 |价值 | | 1 | 2018-09-12 02:29:31.154 | 7.139 | | 1 | 2018-09-12 02:40:46.724 | 7.254 | | 2 | 2018-09-06 02:40:46.724 | 132.451 | | 1 | 2018-09-12 02:42:19.841 | 7.645 | | 3 | 2018-09-12 03:01:45.811 | 45.276 | | 1 | 2018-09-12 03:12:59.121 | 7.421 | | 2 | 2018-09-12 03:12:59.121 | 130.789 | | 1 | 2018-09-12 03:15:33.467 | 7.121 | | 2 | 2018-09-12 03:15:33.467 | 136.198 | | 3 | 2018-09-12 03:15:33.467 | 46.971 | | 2 | 2018-09-12 03:27:13.642 | 131.879 | | 3 | 2018-09-12 03:27:13.642 | 44.645 | | 1 | 2018-09-12 03:30:27.564 | 7.691 | | ... | ... | ... |

我的目标是进行单个查询以获取 Id 1、2 和 3 的日期范围之间的值并将它们合并在一起。

结果将是这样的:

{ Timestamp: "2018-09-12 02:29:31.154", id1: 7.123, id2: null, id3: null }
{ Timestamp: "2018-09-12 02:40:46.724", id1: 7.254, id2: 132.451, id3: null }
{ Timestamp: "2018-09-12 02:42:19.841", id1: 7.645, id2: null, id3: null }
{ Timestamp: "2018-09-12 03:01:45.811", id1: null, id2: null, id3: 45.276 }
{ Timestamp: "2018-09-12 03:12:59.121", id1: 7.421, id2: 130.789, id3: null }
{ Timestamp: "2018-09-12 03:15:33.467", id1: 7.121, id2: 136.198, id3: 46.971 }
{ Timestamp: "2018-09-12 03:27:13.642", id1: null, id2: 131.879, id3: 44.645 }
{ Timestamp: "2018-09-12 03:30:27.564", id1: 7.691, id2: null, id3: null }


是否可以在单个查询中进行?

【问题讨论】:

  • id 最大是 3 吗?
  • 您希望结果显示在一个长字符串中还是 4 列中?
  • 没有在我的例子中最大为 3...还有更多。
  • 我需要一个长字符串中的结果
  • @Broge - 您使用哪个版本的 SQL Server?

标签: sql-server linq tsql merge


【解决方案1】:
var ids = new List<int> { 1, 2, 3};

var result = (from item in db.Table
              where ids.Contains(item.id) && item.Timestamp > fromDate && item.Timestamp < toDate
              group item by item.Timestamp into sub
              select new 
              {
                  Timestamp = sub.Key,
                  id1 = sub.Where(x => x.id == 1).Select(x => x.Value).FirstOrDefault(),
                  id2 = sub.Where(x => x.id == 2).Select(x => x.Value).FirstOrDefault(),
                  id3 = sub.Where(x => x.id == 3).Select(x => x.Value).FirstOrDefault()
              }).ToList();

【讨论】:

  • 我从未见过这种类型的查询。请告诉我这个查询的标签。
  • 我需要一个日期范围之间的查询,例如:2018-09-12 00:00:00.0002018-09-12 23:59:59.999
  • @Broge,添加日期过滤器
  • @IdontKnowEnglish - 这似乎是“linq”
  • 好的.. 谢谢@SlavaUtesinov.. 我会关注这个标签的。
【解决方案2】:

如何使用字符串聚合,在 SQL Server 2017 中使用 STRING_AGG() 函数 [documentation] 它会像这样工作:

SELECT [Timestamp]
  -- building string very similar to what you've posted; you can certainly play with this column and format it the way you want
  , STRING_AGG(CONCAT('id', CAST(Id AS nvarchar(50)), ': ', ISNULL(CAST([Value] AS nvarchar(50)), N'NULL')), ', ')
FROM schema.Table
GROUP BY [Timestamp];

如果您使用的是旧版本的 SQL Server,逻辑将是相同的,您只需采用自定义的字符串聚合方式,例如以下其中之一:

我自己通常在STRING_AGG()不可用时使用XML解决方案。

【讨论】:

  • 只需将STRING_AGG 替换为第一个链接中的完成方式即可。
猜你喜欢
  • 1970-01-01
  • 2013-10-19
  • 1970-01-01
  • 2011-01-11
  • 2019-08-06
  • 1970-01-01
  • 1970-01-01
  • 2015-10-12
  • 1970-01-01
相关资源
最近更新 更多