经过广泛研究后,我的理解是你无法在Simple.Data中进行子查询。然而,有足够的连接和排序,我偶尔会看到一个CTE弹出,这将符合我的目的。我已经创建了一个小提琴来演示我想用Simple.Data(在ADO.NET之上)实现的目标,我只是无法弄清楚如何在simple.data查询中构建它(或者一组查询。)
如果我有两张桌子:
CREATE TABLE Request
(id int,
payload varchar(50))
;
CREATE TABLE Response
(id int,
requestId int,
payload varchar(50),
sortableValue int,
filterField bit)
;
如何获得子表的过滤顶部结果? e.g。
SELECT *
FROM Request ereq
JOIN
Response eres
ON eres.id = (SELECT TOP 1 id from Response
WHERE requestId = ereq.id AND filterField = 1
ORDER BY sortableValue DESC)
或使用CTE
WITH sorted_content AS
(
SELECT ROW_NUMBER() OVER (PARTITION BY requestId ORDER BY sortableValue DESC) as rowId,
*
FROM Response
WHERE filterField = 1
)
SELECT *
FROM Request ereq
JOIN sorted_content sorted_eres
ON sorted_eres.requestId = ereq.id
AND sorted_eres.rowId = 1
http://sqlfiddle.com/#!6/33ac5/17
目标是能够在Simple.Data表达式中执行与上述表达式类似的操作,以便我可以利用分页。如果我在事后过滤,则分页变得有问题/昂贵。
答案 0 :(得分:0)
我希望有人会提出更好的解决方案,但我们最终提出的解决方案是使用View:
CREATE VIEW FilteredResponse
AS
SELECT Response1.*
FROM (SELECT (SELECT TOP (1) id
FROM Response AS ri
WHERE ( requestId = ro.requestId )
AND ( filterField = 1 )
ORDER BY sortableValue DESC) AS rid
FROM (SELECT DISTINCT requestId
FROM Response) AS ro) AS sortedResponse
INNER JOIN Response AS Response1
ON sortedResponse.rid = Response1.id
现在,以下SQL生成了相应的结果:
SELECT * FROM Request ereq
JOIN FilteredResponse eres ON eres.requestId = ereq.id
这是一个非常简单的Simple.Data查询:
_db.Request.FindAll().Join(_db.FilteredResponse).On(_db.FilteredResponse.RequestId == _db.Request.Id)
完全小提琴:http://sqlfiddle.com/#!6/fe341/3/0
我们可以避免这种情况,因为我们的filterField值对于所有情况都是已知的。这不适用于动态filterField。
我仍然希望社区中的某些人能够找到更清晰的方式来实现这一目标。