SQL Server Group By Query, используя несколько значений - PullRequest
0 голосов
/ 10 июля 2009

Я новичок в 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

Мне нужно найти начальное и конечное значение для каждого из приводов. Обычный запрос GROUP BY с использованием MIN и MAX группирует все приводные диски это одно и то же вместе, но мне нужно держать каждого отдельно. То есть вывод должен выглядеть так:

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 ]

3 голосов
/ 10 июля 2009

Вы явно хотите разделить поездки - результаты, которые, как вы говорите, вы хотите получить, например, Драйвер 401 включает в себя первый ряд, затем мин / макс пробегает второй набор строк для этого драйвера. Таким образом, похоже, что вам не хватает столбца «JourneyID» или аналогичного. Первая строка будет иметь одно значение для JourneyID, а второй набор строк будет иметь одинаковое значение JourneyID, но отличается от значения для первой строки.

Если у вас есть этот столбец, вы можете добавить его в предложение Group By.

1 голос
/ 10 июля 2009
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
1 голос
/ 10 июля 2009

Похоже, мне нужно что-то вроде этого:

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

Это запрос, который вы выполняете?

0 голосов
/ 10 июля 2009

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
...