Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在MSSQL中按一列排序_Sql_Sql Server_Tsql_Date_Greatest N Per Group - Fatal编程技术网

在MSSQL中按一列排序

在MSSQL中按一列排序,sql,sql-server,tsql,date,greatest-n-per-group,Sql,Sql Server,Tsql,Date,Greatest N Per Group,我有以下SQL表: [日历] [CalendarId] [Name] 样本数据: CalendarId ResourceKey Name 1 1 tk1-Room1 2 2 tk1-Room2 3 3 tk1-noentries CalendarId Start End 1

我有以下SQL表:

[日历]

[CalendarId]
[Name]
样本数据:

CalendarId  ResourceKey    Name
1           1              tk1-Room1
2           2              tk1-Room2
3           3              tk1-noentries
CalendarId  Start                            End
1           2019-11-18 16:00:00.0000000      2019-11-18 17:00:00.0000000
1           2019-11-19 16:00:00.0000000      2019-11-19 17:00:00.0000000
2           2019-11-25 16:00:00.0000000      2019-11-25 17:00:00.0000000
1           2019-11-25 17:00:00.0000000      2019-11-25 18:00:00.0000000

[日历条目]

[CalendarId]
[CalendarEntryId]
[Start]
[End]
样本数据:

CalendarId  ResourceKey    Name
1           1              tk1-Room1
2           2              tk1-Room2
3           3              tk1-noentries
CalendarId  Start                            End
1           2019-11-18 16:00:00.0000000      2019-11-18 17:00:00.0000000
1           2019-11-19 16:00:00.0000000      2019-11-19 17:00:00.0000000
2           2019-11-25 16:00:00.0000000      2019-11-25 17:00:00.0000000
1           2019-11-25 17:00:00.0000000      2019-11-25 18:00:00.0000000

预期产出:

Name             StartDate             EndDate                ResourceKey
tk1-Room1        2019-11-25 17:00:00   2019-11-25 17:00:00    1
tk1-Room2        2019-11-25 16:00:00   2019-11-25 17:00:00    2
tk1-noentries    NULL                  NULL                   3
我试图列出所有
日历
条目及其相应的开始(最近)和结束时间

我有以下部分工作的代码:

SELECT Name,StartDate,ResourceKey FROM [Calendar].[dbo].[Calendar] CAL
LEFT JOIN(
    SELECT 
        CalendarId, 
        MAX(ENT.[Start]) as StartDate
    FROM [CalendarEntry] ENT
    GROUP BY CalendarId
    )
AS ST on CAL.CalendarId = ST.CalendarId
但是,如果我要将该列包括在我的子选择中,例如:

    SELECT 
        CalendarId, 
        MAX(ENT.[Start]) as StartDate,
        ENT.[End] as endDate
我得到以下错误:

Column 'CalendarEntry.End' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
但是,现在将其包含在组中会导致每个日历返回多个CalendarEntry行

对于我来说,从允许我访问所有列的CalendarEntry中获取最近一行的最佳方法是什么


谢谢

这是一个典型的每组前1题

您可以使用
行编号()

或者,您可以使用相关子查询进行筛选:

select c.*, e.*
from [Calendar].[dbo].[Calendar] c
left join [CalendarEntry] e 
    on c.CalendarId = e.CalendarId
    and c.Start = (
        select max(e1.Start) from [CalendarEntry] e where c.CalendarId = e1.CalendarId
    ) 

这是一个典型的每组前1题

您可以使用
行编号()

或者,您可以使用相关子查询进行筛选:

select c.*, e.*
from [Calendar].[dbo].[Calendar] c
left join [CalendarEntry] e 
    on c.CalendarId = e.CalendarId
    and c.Start = (
        select max(e1.Start) from [CalendarEntry] e where c.CalendarId = e1.CalendarId
    ) 
我试图列出所有日历条目,以及它们相应的开始(最近)和结束时间

我将此解释为每个
CalendarId
CalendarEntry
中的最新记录:

select ce.*
from CalendarEntry ce
where ce.StartDate = (select max(ce2.StartDate)
                      from CalendarEntry ce2
                      where ce2.CalendarId = ce.CalendarId
                     );
我试图列出所有日历条目,以及它们相应的开始(最近)和结束时间

我将此解释为每个
CalendarId
CalendarEntry
中的最新记录:

select ce.*
from CalendarEntry ce
where ce.StartDate = (select max(ce2.StartDate)
                      from CalendarEntry ce2
                      where ce2.CalendarId = ce.CalendarId
                     );
你也可以尝试,但是从性能角度来看,我们的答案是更好的方法

SELECT Name,
       StartDate,
       EndDate,
       ResourceKey
FROM dbo.Calendar AS C
    OUTER APPLY
(
    SELECT TOP 1 *
    FROM dbo.CalendarEntry
    WHERE CalendarId = C.CalendarId
    ORDER BY StartDate DESC,
             EndDate DESC
) AS K;
您也可以尝试/(在SQL Server 2012及更高版本中提供)函数,如下所示,不过从性能角度来看,我们的答案还是更好的:

SELECT DISTINCT
       Name,
       LAST_VALUE(StartDate) OVER (PARTITION BY C.CalendarId
                                   ORDER BY StartDate,EndDate
                                   ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING),
       LAST_VALUE(EndDate) OVER (PARTITION BY C.CalendarId
                                 ORDER BY StartDate,EndDate
                                 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING),
       ResourceKey
FROM dbo.Calendar AS C
    LEFT JOIN dbo.CalendarEntry
        ON CalendarEntry.CalendarId = C.CalendarId;
如果要使用FIRST_VALUE函数,则应按如下方式重写顺序:

ORDER BY StartDate DESC,EndDate DESC
而且,您也不需要指定无界前向和无界后向之间的
部分

SELECT DISTINCT
       Name,
       FIRST_VALUE(StartDate) OVER (PARTITION BY C.CalendarId
                                   ORDER BY StartDate DESC,EndDate DESC),
       FIRST_VALUE(EndDate) OVER (PARTITION BY C.CalendarId
                                 ORDER BY StartDate DESC,EndDate DESC),
       ResourceKey
FROM dbo.Calendar AS C
    LEFT JOIN dbo.CalendarEntry
        ON CalendarEntry.CalendarId = C.CalendarId;
你也可以尝试,但是从性能角度来看,我们的答案是更好的方法

SELECT Name,
       StartDate,
       EndDate,
       ResourceKey
FROM dbo.Calendar AS C
    OUTER APPLY
(
    SELECT TOP 1 *
    FROM dbo.CalendarEntry
    WHERE CalendarId = C.CalendarId
    ORDER BY StartDate DESC,
             EndDate DESC
) AS K;
您也可以尝试/(在SQL Server 2012及更高版本中提供)函数,如下所示,不过从性能角度来看,我们的答案还是更好的:

SELECT DISTINCT
       Name,
       LAST_VALUE(StartDate) OVER (PARTITION BY C.CalendarId
                                   ORDER BY StartDate,EndDate
                                   ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING),
       LAST_VALUE(EndDate) OVER (PARTITION BY C.CalendarId
                                 ORDER BY StartDate,EndDate
                                 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING),
       ResourceKey
FROM dbo.Calendar AS C
    LEFT JOIN dbo.CalendarEntry
        ON CalendarEntry.CalendarId = C.CalendarId;
如果要使用FIRST_VALUE函数,则应按如下方式重写顺序:

ORDER BY StartDate DESC,EndDate DESC
而且,您也不需要指定无界前向和无界后向之间的
部分

SELECT DISTINCT
       Name,
       FIRST_VALUE(StartDate) OVER (PARTITION BY C.CalendarId
                                   ORDER BY StartDate DESC,EndDate DESC),
       FIRST_VALUE(EndDate) OVER (PARTITION BY C.CalendarId
                                 ORDER BY StartDate DESC,EndDate DESC),
       ResourceKey
FROM dbo.Calendar AS C
    LEFT JOIN dbo.CalendarEntry
        ON CalendarEntry.CalendarId = C.CalendarId;

样本数据和预期结果将有所帮助。您的代码中有未作为表的一部分提及的列。当GROUP BY、UNION和SELECT DISTINCT时,ORDER BY中只能使用SELECT列表项。非常有意义。样本数据和期望的结果会有所帮助。您的代码中有未作为表的一部分提及的列。当GROUP BY、UNION和SELECT DISTINCT时,ORDER BY中只能使用SELECT列表项。这很有道理。但这不会被证明是日历。名称@VigneshKumarA。如果需要,您可以在外部查询中轻松地
加入它。在这种情况下,将丢失CalendarId=3的记录!但这不会被证明是日历。名称
@VigneshKumarA。如果需要,您可以在外部查询中轻松地
加入它。在这种情况下,将丢失CalendarId=3的记录!这是有效的,但仔细检查,似乎任何没有任何条目的日历都不会被返回。。。我的测试数据包含13个日历,只有12个有条目。我只得到了12个结果。这是有效的,但仔细检查,似乎任何没有任何条目的日历都不会被返回。。。我的测试数据包含13个日历,只有12个有条目。我只得到了12个结果。