首先让我说我不是数据库人,而且我完全不知道自己在做什么。即使与问题没有直接关系,我也欢迎任何改进的意见或建议。
无论如何,我有两个表,事件和事件。非常典型的设置:Occurrences具有Events.Id的外键,创建一对多的关系。出现时有一个StartDate和EndDate(尽管名称都是完整的日期时间值)。所以我想要做的是为所有事件选择所有列,其中Occurrences中至少有一个相关行,其中StartDate的未来值(尚未启动)或EndDate的未来值(已启动,但尚未结束)
我从以下内容中得到了以下查询(这里有一些逻辑用于获取“实时”事件,已发布但未过期等等。非常直接的内容):
DECLARE @PublishedStatus INT = 2
SELECT *
FROM [dbo].[Events] e
INNER JOIN [dbo].[Occurrences] o
ON e.Id = o.EventId
AND (o.StartDate > GETUTCDATE() OR o.EndDate > GETUTCDATE())
WHERE e.Status = @PublishedStatus
AND e.PublishDate IS NOT NULL
AND e.PublishDate <= GETUTCDATE()
AND (e.ExpireDate IS NULL OR e.ExpireDate > GETUTCDATE())
问题是我现在想要通过选定的Occurrences行中的最小StartDate值来排序。如果我尝试添加:
ORDER BY MIN(o.StartDate)
如果不添加:
,它将无效GROUP BY e.Id
然后当然需要将我的选择更改为
SELECT e.Id
现在,问题是我需要来自Events的所有列,而不仅仅是Id。我知道这是GROUP BY的工作方式,所以这并不奇怪。我只是想找到一个中间地带,我可以在某种程度上同时做两件事。不幸的是,正如我在开始时说的那样,我不是这方面的专家,而且我已经达到了目前能力的极限。
此外,对于它的价值,这将是存储过程的基础。它进入了一个ORM,所以我需要返回所有列来正确实例化代表该表的类。我不希望显式指定所有列名,因为我需要始终将此存储过程与对表的模式所做的任何更新同步,如果有任何更新(添加其他列等),但是这是达到我需要的唯一方式,我会处理。
答案 0 :(得分:1)
如果我理解正确(我不确定)你可以尝试这样的事情
DECLARE @PublishedStatus INT = 2
SELECT e.*
FROM
(
SELECT e.Id, MIN(o.StartDate) MinStartDate
FROM [dbo].[Events] e INNER JOIN [dbo].[Occurrences] o
ON e.Id = o.EventId
AND (o.StartDate > GETUTCDATE() OR o.EndDate > GETUTCDATE())
WHERE e.Status = @PublishedStatus
AND e.PublishDate IS NOT NULL
AND e.PublishDate <= GETUTCDATE()
AND (e.ExpireDate IS NULL OR e.ExpireDate > GETUTCDATE())
GROUP BY e.Id
) q JOIN [dbo].[Events] e
ON q.Id = e.Id
ORDER BY MinStartDate
答案 1 :(得分:1)
ORDER BY MIN(o.StartDate)表示您想按升序订购StartDate。对吗? 因此,在这种情况下,您只需添加Order By StartDate,如: -
DECLARE @PublishedStatus INT = 2
SELECT *
FROM [dbo].[Events] e
INNER JOIN [dbo].[Occurrences] o
ON e.Id = o.EventId
AND (o.StartDate > GETUTCDATE() OR o.EndDate > GETUTCDATE())
WHERE e.Status = @PublishedStatus
AND e.PublishDate IS NOT NULL
AND e.PublishDate <= GETUTCDATE()
AND (e.ExpireDate IS NULL OR e.ExpireDate > GETUTCDATE())
Order By o.StartDate ASC