SQL Server Group By Query使用多个值

时间:2009-07-10 10:21:50

标签: sql-server tsql group-by

我是Microsoft SQL Server的新手,并且因为GROUP BY查询无法满足我的要求而感到沮丧。该表如下:

make    model   distancefrom    distanceto  driverid
toyota  yaris   358.2   368.2   401
toyota  yaris   368.2   378.7   103
toyota  yaris   378.7   382.2   103
toyota  yaris   382.2   392.2   103
toyota  yaris   392.2   403.6   103
toyota  yaris   403.6   414.3   103
toyota  yaris   414.3   419.4   103
toyota  yaris   419.4   430.2   103
toyota  yaris   430.2   439.2   401
toyota  yaris   439.2   446     401
toyota  yaris   446     457.2   401
toyota  yaris   457.2   460.1   401
toyota  yaris   460.1   468.6   401
toyota  yaris   468.6   480.3   401
toyota  yaris   480.3   486.2   103
toyota  yaris   486.2   490     103
toyota  yaris   490     501.1   103
toyota  yaris   501.1   512.5   103
toyota  yaris   512.5   523.1   103
toyota  yaris   523.1   532.6   401
toyota  yaris   532.6   542.7   401
toyota  yaris   542.7   551.1   401

我需要找到每个驱动程序的起始值和结束值。 使用MIN和MAX的正常GROUP BY查询将所有驱动程序分组 这是相同的,但我需要保持每个单独的。即该 输出应该如下所示:

make    model   distancefrom    distanceto  driverid
toyota  yaris   358.2   368.2   401
toyota  yaris   368.2   430.2   103
toyota  yaris   430.2   480.3   401
toyota  yaris   480.3   523.1   103
toyota  yaris   523.1   551.1   512

任何帮助都将不胜感激。

4 个答案:

答案 0 :(得分:3)

您显然希望将旅程分开 - 您说的结果例如:驱动程序401涉及第一行,然后min / max在该驱动程序的第二组行上运行。所以看起来好像你错过了“JourneyID”专栏或类似专栏。第一行将有一个JourneyID值,第二行将具有相同的JourneyID值但不同于第一行的值。

如果您有该列,则可以将其添加到Group By子句中。

答案 1 :(得分:1)

在我看来你需要这样的东西:

SELECT make, model, driverid, min(distancefrom), max(distancefrom), min(distanceto), max(distanceto)
FROM table
GROUP BY make, model, driverid

这是您运行的查询吗?

答案 2 :(得分:1)

SELECT  make, model, driverid
FROM    (
        SELECT  make, model, driverid,
                ROW_NUMBER() OVER (PARTITION BY make, model, driverid ORDER BY distancefrom) AS rns,
                ROW_NUMBER() OVER (PARTITION BY make, model, driverid ORDER BY distancefrom DESC) AS rne
        FROM    mytable
        ) q
WHERE   1 IN (rns, rne)

如果您在(make, model, driverid, distance)上有索引,则此索引可以更高效:

SELECT  m.make, m.model, m.driverid,
        (
        SELECT  TOP 1 distancefrom
        FROM     mytable mi
        WHERE    mi.make = m.make
                 AND mi.model = m.model
                 AND mi.driverid = m.driverid
        ORDER BY
                 distancefrom
        ),
        (
        SELECT  TOP 1 distancefrom
        FROM     mytable mi
        WHERE    mi.make = m.make
                 AND mi.model = m.model
                 AND mi.driverid = m.driverid
        ORDER BY
                 distancefrom DESC
        )
FROM    (
        SELECT  DISTINCT make, model, driverid
        FROM    mytable
        ) m

答案 3 :(得分:0)

MS SQL 2005/2008解决方案。无法在MS SQL 2000上运行。

create table #journeySegment (make varchar(100) not null
        , model varchar(100) not null
        , distanceFrom decimal(10,2) not null
        , distanceTo decimal(10, 2) not null
        , driverId int not null -- References blah
        , CONSTRAINT data_U unique (make, model, driverId, distanceFrom)
        , CONSTRAINT data_FromTo_CHK check (distanceFrom <= distanceTo))


insert into #journeySegment values ('toyota', 'yaris', 358.2, 368.2, 401)
insert into #journeySegment values ('toyota', 'yaris', 368.2, 378.7, 103)
insert into #journeySegment values ('toyota', 'yaris', 378.7, 382.2, 103)
insert into #journeySegment values ('toyota', 'yaris', 382.2, 392.2, 103)
insert into #journeySegment values ('toyota', 'yaris', 392.2, 403.6, 103)
insert into #journeySegment values ('toyota', 'yaris', 403.6, 414.3, 103)
insert into #journeySegment values ('toyota', 'yaris', 414.3, 419.4, 103)
insert into #journeySegment values ('toyota', 'yaris', 419.4, 430.2, 103)
insert into #journeySegment values ('toyota', 'yaris', 430.2, 439.2, 401)
insert into #journeySegment values ('toyota', 'yaris', 439.2, 446, 401)
insert into #journeySegment values ('toyota', 'yaris', 446, 457.2, 401)
insert into #journeySegment values ('toyota', 'yaris', 457.2, 460.1, 401)
insert into #journeySegment values ('toyota', 'yaris', 460.1, 468.6, 401)
insert into #journeySegment values ('toyota', 'yaris', 468.6, 480.3, 401)
insert into #journeySegment values ('toyota', 'yaris', 480.3, 486.2, 103)
insert into #journeySegment values ('toyota', 'yaris', 486.2, 490, 103)
insert into #journeySegment values ('toyota', 'yaris', 490, 501.1, 103)
insert into #journeySegment values ('toyota', 'yaris', 501.1, 512.5, 103)
insert into #journeySegment values ('toyota', 'yaris', 512.5, 523.1, 103)
insert into #journeySegment values ('toyota', 'yaris', 523.1, 532.6, 513)
insert into #journeySegment values ('toyota', 'yaris', 532.6, 542.7, 513)
insert into #journeySegment values ('toyota', 'yaris', 542.7, 551.1, 513)

-- ASSUMPTIONS:
-- journeySegments do not overlap.
-- distanceFrom and distanceTo are exact numeric types.

; with potentialJourney (make, model, journeyFrom, journeyTo, driverId, level) as
    (-- Find the starting segment for each journey.
    select make,
        model, 
        distanceFrom, 
        distanceTo,
        driverId,
        0
    from #journeySegment A
    where not exists
        (select *
        from #journeySegment B
        where B.make = A.Make
        and B.model = A.model
        and B.driverId = A.driverId 
        and B.DistanceTo = A.DistanceFrom)
    union all
    -- add on next segment.
    select PJ.make
        , PJ.model
        , PJ.journeyFrom
        , nextJS.distanceTo
        , PJ.driverId
        , PJ.level + 1
    from potentialJourney PJ
    inner join #journeySegment nextJS
        on nextJS.make = PJ.Make
        and nextJS.model = PJ.Model
        and nextJs.driverId = PJ.driverId
        and nextJs.distanceFrom = PJ.journeyTo)
select M.make
    , M.Model
    , M.journeyFrom
    , M.journeyTo
    , M.driverId
from potentialJourney M
-- Eliminate the partial solutions
where not exists
    (select *
    from potentialJourney S
    where S.make = M.make
    and S.model = M.model
    and S.journeyFrom = M.journeyFrom
    and S.driverId = M.driverId
    and S.level > M.level)
order by journeyFrom