2009-07-10 14 views
0

私はMicrosoft SQL Serverを初めて使用しており、必要な処理を実行しないGROUP BYクエリに不満を抱いています。テーブルは次のとおりです。複数の値を使用したクエリによるSQL Serverグループ

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 

各driveridの開始値と終了値を見つける必要があります。 MINとMAXを使用する通常のGROUP BYクエリでは、同じドライバID がすべてグループ化されますが、それぞれを別々にする必要があります。私。 の出力は次のようになります。

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 

助けてください。

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

これはあなたが実行したクエリです:あなたはこのような何かを必要とするよう

+1

これを再フォーマットできますか?データを選択し、0101アイコンを使用して "コード"としてマークしてみてください。 –

+0

鎖をまとめたいですか? DriverId = 401を見ると、出力に2行あります。 358.2〜368.2、次いで430.2〜480.3である。そして、あなたが2列である理由は、入力データの368.2から480.3の間のギャップのためです。あれは正しいですか? –

+0

そして、どのバージョンのMS SQL Server? 2005年と2008年には、これを簡単にするためのツールが用意されています。 –

答えて

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)にインデックスを持っている場合は、この1つは、より効率的になります

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

あなたは明確に旅を​​分離しておくにしたい - あなたは、例えばのためにしたいと言う結果をドライバ401は第1の行を含み、そのドライバの第2の行のセットをmin/max実行する。したがって、「JourneyID」列などがない場合があります。最初の行はJourneyIDに1つの値を持ち、2番目の行はすべてJourneyIDと同じ値を持ちますが、最初の行とは異なります。

この列がある場合は、Group By句に追加できます。

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