返回ID行与另一列中的最小值匹配

时间:2018-05-31 18:16:53

标签: sql sql-server tsql sql-server-2014

目前这就是我所拥有的 -

select ServiceName, MethodName, 
       min(duration) AS duration, min(ID) as ID, count(id) As count
from dbo.log
group by ServiceName, MethodName

我需要返回的ID与min(duration)值匹配。目前我不确定它返回的ID是什么,但它不是持续时间最短的ID。

3 个答案:

答案 0 :(得分:1)

您应该尝试如下查询。该查询使用Row_number()但您也可以使用rank(),以防您需要多行,以防许多记录具有相同的最小持续时间。看到一个不错的link on explanation

但是,无论多个行具有相同服务名称和方法名称的最小持续时间,下面的查询都将返回单行

def combine_sheets(self, inputFiles):
    logging.info('combining input files to one spreadsheet')

    '''
    create a pandas excel writer using xlsxwriter as the engine
    pandas and xlsxwriter will need to be installed on server running script
    '''
    outputFile = os.path.join(self.processingDir, 'combined_ncoa_report.xlsx')
    writer = pandas.ExcelWriter(outputFile, engine='openpyxl')

    df = pandas.DataFrame()

    for inputFile in inputFiles:
        logging.info('reading spreadsheet %s' % (os.path.split(inputFile)[-1]))

        # read input xlsx to pandas dataframe
        book = load_workbook(inputFile)
        writer.book = book
        writer.sheets = {ws.title: ws for ws in book.worksheets}

        for sheetname in writer.sheets:
            df.to_excel(writer,sheet_name=sheetname, startrow=writer.sheets[sheetname].max_row, index = False,header= False)

        writer.save()

    # closing writer
    writer.close()

答案 1 :(得分:1)

如果你想同时使用最小持续时间和它的id,那么最简单的方法是使用两个窗口函数。

SELECT DISTINCT ServiceName, MethodName
    , MIN(Duration) OVER (PARTITION BY ServiceName, MethodName ORDER BY Duration ASC)
    , FIRST_VALUE(Id) OVER (PARTITION BY ServiceName, MethodName ORDER BY Duration ASC)
FROM log

对于持续时间为MIN的ORDER BY子句似乎没有必要,但是通过重用该分区,可以同时处理这两个函数,而不必将它们分成单独的集合并重新组合。理解的最佳方法是从中获取顺序并查看查询计划,并查看它如何添加嵌套循环和许多其他额外步骤。长话短说,这最终产生了一个非常简短有效的计划。

我希望很明显如何检索正确的ID。基本上,这依赖于这样一个事实,即对一个集合进行排序会导致第一行中的任何值与排序中使用的最小值/最大值相关。

如果多个ID与持续时间匹配,并且您希望全部看到它们,则可以执行以下操作。您可以使用TOP将结果限制为特定行数。

SELECT l1.ServiceName, l1.MethodName, l1.Duration, x.Id 
FROM (
    SELECT ServiceName, MethodName, MIN(Duration) Duration 
    FROM log GROUP BY ServiceName, MethodName
) l1 
CROSS APPLY (
    SELECT TOP 10 Id 
    FROM log l2 WHERE l2.ServiceName = l1.ServiceName 
        AND l2.MethodName = l1.MethodName 
        AND l2.Duration = l1.Duration
) x

答案 2 :(得分:0)

只是添加一个不同的选项,我认为这个也应该有效:

with s as (
  select ServiceName, MethodName, 
      min(duration) AS duration, count(id) As count
    from dbo.log
    group by ServiceName, MethodName
)
select s.*, l.id
  from s 
  join dbo.log l on s.ServiceName = l.ServiceName 
                and s.Methodname = l.MethodName
                and s.duration = l.duration;

如果有多个行具有相同的最小值,则此查询将显示同一服务的多个行。