此 SQL 的 Cosmos DB 等效项
Posted
技术标签:
【中文标题】此 SQL 的 Cosmos DB 等效项【英文标题】:CosmoDB equivalent of this SQL 【发布时间】:2021-12-26 09:35:21 【问题描述】:与此等效的好的 cosmodb sql 是什么?我有几乎相同的 sql 在 postgres 中的虚拟表上工作,但似乎无法在 cosmodb 上复制它。
SELECT c.device_id FROM c
WHERE (c.timestamp, c.device_id)
IN (
SELECT c.device_id, MAX(c.timestamp) FROM c WHERE c.device_id in ('00137A100000D2DB', '00137A100000D299') GROUP BY c.device_id
)
导致错误:
Gateway Failed to Retrieve Query Plan: Message: "errors":["severity":"Error","location":"start":49,"end":50,"code":"SC1001","message":"Syntax error, incorrect syntax near ','."]
ActivityId: ef246154-4a6b-4657-9cb3-8437a793053e, Microsoft.Azure.Documents.Common/2.14.0, Microsoft.Azure.Documents.Common/2.14.0
示例文档
"device_id": "00137A100000D299",
"timestamp": 1602127299000,
"battery": 3.6,
"battery_unit": "V",
"temperature": 0.76,
"temperature_unit": "°C",
"humidity": 36.28,
"humidity_unit": "%",
"id": "87340b02-2a5d-48db-9dff-97a14785cb7f"
基本上这个想法是获取一些已知设备 ID 的最新时间戳,然后使用它来获取该时间戳的最新数据。
【问题讨论】:
【参考方案1】:Cosmos DB SQL API 不允许基于子查询或cross document joins 的结果进行任何类型的查找(尽管在 Mongo API 和 Graph API 中可以在文档之间进行查找) - 所以您需要从客户端执行一次查询,然后在第二次查询中使用该值。
或者您可以调整 my answer here 中的 SQL 以在单个聚合查询中完成所有操作。
【讨论】:
你能添加一个例子吗?所以查询应该只获取每个 device_id 的最新行【参考方案2】:正如@martin-smith 所提到的,除了简单的聚合之外,您不能使用单个查询来实现跨文档魔法。
添加一个更实用的说明,如果您碰巧每个时间戳只有一个数据点,那么您最简单的选择就是对每个设备执行一个简单的有序查询:
SELECT top 1 * FROM c
where c.device_id = @deviceId
order by timestamp desc
通常只发送多个简单且索引良好的查询比尝试通过编写复杂的 SQL 查询来优化那些 10 毫秒的请求到服务器更便宜且更易于维护。
【讨论】:
有没有办法在两个查询中有效地做到这一点?而不是“N”查询,其中“N”是 device_id 的数量?我一直在试验,但似乎不支持 UNION ALL 和其他各种功能,除了使用 max 运算符之外,没有办法在两个查询中有效地做到这一点,这不是我想要的,因为它做了太多的工作。 我不认为只有 2 个查询有任何更简单和/或更好的 RU 使用率。您是否有理由优化查询数量?这个 N 平均有多大?以上是关于此 SQL 的 Cosmos DB 等效项的主要内容,如果未能解决你的问题,请参考以下文章