6

私はこれを検索しましたが、同様の質問と回答はすべて機能しないほど異なっています。

次のフィールドを持つテーブルがあります:人、物、パーデート。人が新しいものを購入するたびに、新しいレコードが入力されます。

人が何か「もの」を購入した連続した月を数えたいと思います (thing01 または thing02 は関係ありません)。連続する purdays に休憩がある場合は、カウントを最初からやり直す必要があります。

データを同封して、これで終わりたいと思います。

| Person     | Consec Days |
| person_01  | 3           |
| person_02  | 3           |
| person_02  | 2           |

個人の個別のリスト、extract(year_month from purdate) を取得できることはわかっていますが、これはこのSQLFIDDLEで実行しましたが、連続したレコードのみをカウントして、区切りからやり直す方法がわかりません (私のデータのように、person_02 が 3 月と 5 月の間に壊れています。)

データは次のとおりです。

create table records (
  person varchar(32) not null,
  thing varchar(32) not null,
  purdate datetime not null
);

insert into records (person, thing, purdate) values
  ('person_01', 'thing01', '2014-01-02'),
  ('person_01', 'thing02', '2014-01-02'),
  ('person_01', 'thing02', '2014-02-27'),
  ('person_01', 'thing02', '2014-03-27'),
  ('person_02', 'thing02', '2014-01-28'),
  ('person_02', 'thing01', '2014-02-28'),
  ('person_02', 'thing02', '2014-03-28'),
  ('person_02', 'thing02', '2014-05-29'),
  ('person_02', 'thing02', '2014-06-29')
;
4

2 に答える 2

5

変数 (または非常に複雑な相関サブクエリ) を使用して、MySQL でこれを行うことができます。他のデータベースでは、ウィンドウ/分析関数を使用します。

ロジックは次のとおりです。

  1. 月に1行、お買い上げの方にプレゼント。
  2. 変数を使用して、連続する月の各グループに「グループ化」値を割り当てます。
  3. 人物と「グルーピング」値で集計します。

SQL Fiddle でテストされたクエリを次に示します。

select person, count(*) as numMonths
from (select person, ym, @ym, @person,
             if(@person = person and @ym = ym - 1, @grp, @grp := @grp + 1) as grp,
             @person := person,
             @ym := ym
      from (select distinct person, year(purdate)*12+month(purdate) as ym
            from records r
           ) r cross join
           (select @person := '', @ym := 0, @grp := 0) const
      order by 1, 2
     ) pym
group by person, grp;
于 2014-04-21T20:51:03.570 に答える
3

このStackOverflowの回答をガイダンスとして使用しました(データベース内のタイムスタンプを指定して、連続したx日間を確認してください

SELECT a.person, COUNT(1) AS consecutive_months
FROM
(

  SELECT a.person, IF(b.YearMonth IS NULL, @val:=@val+1, @val) AS consec_set
  FROM (
    SELECT DISTINCT person, EXTRACT(YEAR_MONTH from purdate) as YearMonth from records
    ) a
  CROSS JOIN (SELECT @val:=0) var_init
  LEFT JOIN (SELECT DISTINCT person, EXTRACT(YEAR_MONTH from purdate) as YearMonth from records) b ON
      a.person = b.person AND
      a.YearMonth = b.YearMonth + 1
   ) a
GROUP BY a.consec_set
HAVING COUNT(1) >= 2    

ここにSQLFiddleがあります - http://sqlfiddle.com/#!2/cc5c3/55

于 2014-04-21T21:01:03.923 に答える