0

MySQL 5.5.29 これは、私が取り組んでいる mysql クエリですが、成功していません。

SELECT ID, Bike, 
(SELECT IF( MIN( ABS( DATEDIFF(  '2011-1-1', Reading_Date ) ) ) = ABS( DATEDIFF(  '2011-1-1', Reading_Date ) ) , Reading_Date, NULL ) FROM odometer WHERE Bike=10  ) AS StartDate, 
(SELECT IF( MIN( ABS( DATEDIFF(  '2011-1-1', Reading_Date ) ) ) = ABS( DATEDIFF(  '2011-1-1', Reading_Date ) ) , Miles, NULL ) FROM odometer WHERE Bike=10  ) AS BeginMiles, 
(SELECT IF( MIN( ABS( DATEDIFF(  '2012-1-1', Reading_Date ) ) ) = ABS( DATEDIFF(  '2012-1-1', Reading_Date ) ) , Reading_Date, NULL ) FROM odometer  WHERE Bike=10  ) AS EndDate,
(SELECT IF( MIN( ABS( DATEDIFF(  '2012-1-1', Reading_Date ) ) ) = ABS( DATEDIFF(  '2012-1-1', Reading_Date ) ) , Miles, NULL ) FROM odometer WHERE Bike=10  ) AS EndMiles
FROM  `odometer` 
WHERE Bike =10;

結果は次のとおりです。

ID  Bike    StartDate   BeginMiles  EndDate EndMiles
14  10 [->] 2011-04-15  27.0    NULL    NULL
15  10 [->] 2011-04-15  27.0    NULL    NULL
16  10 [->] 2011-04-15  27.0    NULL    NULL

オートバイの所有者は、1 年に 1 回、1 月 1 日またはその前後に走行距離計の測定値を入力します。オートバイの総走行距離を計算したいと考えています。

表の走行距離計のデータは次のようになります: (出典: bmwmcindy.org )

したがって、このバイクの 2011 年の走行距離を計算するには、これらの記録のどれが 2011 年 1 月 1 日に近いかを判断する必要があり、それが記録 14 です。最初の走行距離は 27 になります。1 月 1 日に最も近い記録を見つける必要があります。 .

ここに表があります:

DROP TABLE IF EXISTS `odometer`;
CREATE TABLE IF NOT EXISTS `odometer` (
  `ID` int(3) NOT NULL AUTO_INCREMENT,
  `Bike` int(3) NOT NULL,
  `is_MOA` tinyint(1) NOT NULL,
  `Reading_Date` date NOT NULL,
  `Miles` decimal(8,1) NOT NULL,
  PRIMARY KEY (`ID`),
  KEY `Bike` (`Bike`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=22 ;

テーブルのデータodometer

INSERT INTO `odometer` (`ID`, `Bike`, `is_MOA`, `Reading_Date`, `Miles`) VALUES
(1, 1, 0, '2012-01-01', 5999.0),
(2, 6, 0, '2013-02-01', 14000.0),
(3, 7, 0, '2013-03-01', 53000.2),
(6, 1, 1, '2012-04-30', 10001.0),
(7, 1, 0, '2013-01-04', 31000.0),
(14, 10, 0, '2011-04-15', 27.0),
(15, 10, 0, '2011-12-31', 10657.0),
(16, 10, 0, '2012-12-31', 20731.0),
(19, 1, 1, '2012-09-30', 20000.0),
(20, 6, 0, '2011-12-31', 7000.0),
(21, 7, 0, '2012-01-03', 23000.0);

特定の年 (この場合は 2011 年) の特定の自転車 (この例では Bike=10) の合計マイルを取得するために、終了マイルから開始マイルを差し引くことができるように、さまざまなレコードから日付とマイルを取得しようとしています。

集計関数と、正しいレコードから値を取得する際の問題について、かなり読んだことがあります。答えはサブクエリにあると思いました。しかし、上記のクエリを試すと、最初のレコードからのみデータが取得されます。この場合、終了マイルは 2 番目のレコードから取得する必要があります。

誰かが私を正しい方向に向けてくれることを願っています。

4

1 に答える 1

0

マイルは着実に増加しているはずです。このようなものがうまくいくといいですね:

select year(Reading_Date) as yr,
        max(miles) - min(miles) as MilesInYear
from odometer o
where bike = 10
group by year(reading_date)

残念ながら、あなたの論理はあなたが思っているよりもはるかに難しいです。これは、 SQL Server 2012 や Oracle などのleadおよびlag関数を持つデータベースでは簡単です。

私のアプローチは、毎年の最初と最後の読書日を見つけることです。これは、相関サブクエリを使用して計算できます。

select o.*,
       (select max(date) from odometer o2 where o.bike = o2.bike and o2.date <= o.date - dayofyear(o.date) + 1
       ) ReadDateForYear
from odometer o

次に、これをバイクと年レベルで要約します。1 年目または年初前の読み取り日がない場合は、最初の日付を使用します。

select bike, year(date) as yr,
       coalesce(min(ReadDateForYear), min(date)) as FirstReadDate,
       coalesce(min(ReadDateForNextYear), max(date)) as LastReadDate
from (select o.*,
             (select max(date) from odometer o2 where o.bike = o2.bike and o2.date <= o.date - dayofyear(o.date) + 1
             ) ReadDateForYear,
             (select max(date) from odometer o2 where o.bike = o2.bike and o2.date <= date_add(o.date -      dayofyear(0.date) + 1 + interval 1 year)
             ) ReadDateForNextYear
      from odometer o
     ) o
group by bike, year(date)

これを と呼びましょう。最終結果を得るには、次のようなものが必要です。

select the fields you need
from <q> q join
     odometer s
     on s.bike = q.bike and year(s.date) = q.year join
     odometer e
     on s.bike = q.bike and year(e.date) = q.year

注: この SQL はテストされていません。構文エラーがあると確信しています。

于 2013-01-14T22:45:21.337 に答える