これが、月ごとにグループ化するために私が思いついた解決策です。結果をテストするために、ローカルの MySQL インストールであなたのデータを使用しました。
SELECT
COUNT(*) AS cnt,
GROUP_CONCAT(b.id ORDER BY b.id) AS user_ids,
a.monthgroup
FROM
(
SELECT MONTH(FROM_UNIXTIME(modified_time)) AS monthgroup
FROM jb_resumes
WHERE modified_time BETWEEN
UNIX_TIMESTAMP('2012-03-01 00:00:00')
AND UNIX_TIMESTAMP('2012-04-30 23:59:59')
GROUP BY monthgroup
) a
CROSS JOIN
jb_users b
LEFT JOIN
jb_resumes c ON
b.id = c.user_id
AND a.monthgroup = MONTH(FROM_UNIXTIME(modified_time))
WHERE
b.signup_time < UNIX_TIMESTAMP('2012-04-30 23:59:59')
AND c.user_id IS NULL
GROUP BY
a.monthgroup
ORDER BY
a.monthgroup
少しぎこちないので、もっと洗練された解決策を思い付くことができるかどうか見ていきます。
日のグループ化の解決策:
SELECT
COUNT(*) AS cnt,
GROUP_CONCAT(b.id ORDER BY b.id) AS user_ids,
a.daygroup
FROM
(
SELECT MAKEDATE(YEAR(FROM_UNIXTIME(modified_time)), DAYOFYEAR(FROM_UNIXTIME(modified_time))) AS daygroup
FROM jb_resumes
WHERE modified_time BETWEEN
UNIX_TIMESTAMP('2012-03-01 00:00:00')
AND UNIX_TIMESTAMP('2012-04-30 23:59:59')
GROUP BY daygroup
) a
CROSS JOIN
jb_users b
LEFT JOIN
jb_resumes c ON
b.id = c.user_id
AND a.daygroup = MAKEDATE(YEAR(FROM_UNIXTIME(modified_time)), DAYOFYEAR(FROM_UNIXTIME(modified_time)))
WHERE
b.signup_time < UNIX_TIMESTAMP('2012-04-30 23:59:59')
AND c.user_id IS NULL
GROUP BY
a.daygroup
ORDER BY
a.daygroup
編集:月のグループ化クエリの説明:
あなたは解決策の説明を求めたので、ここに私がそれを理解した方法があります:
最初に行う必要があるmodified_time
のは、時間枠内のすべてのから月のグループを抽出することです。
SELECT MONTH(FROM_UNIXTIME(modified_time)) AS monthgroup
FROM jb_resumes
WHERE modified_time BETWEEN
UNIX_TIMESTAMP('2012-03-01 00:00:00')
AND UNIX_TIMESTAMP('2012-04-30 23:59:59')
GROUP BY monthgroup
その結果:
次に、monthgroup
各ユーザーの組み合わせを比較して、 内で変更時間がないユーザーを特定するには、とすべてのユーザーmonthgroup
の間でデカルト積を作成する必要があります。monthgroup
上記のクエリはすでに を使用しているためGROUP BY
、そのクエリに直接結合することはできませんが、代わりに副選択でラップしてFROM
句に入れる必要があります。
SELECT
a.monthgroup,
b.*
FROM
(
SELECT MONTH(FROM_UNIXTIME(modified_time)) AS monthgroup
FROM jb_resumes
WHERE modified_time BETWEEN
UNIX_TIMESTAMP('2012-03-01 00:00:00')
AND UNIX_TIMESTAMP('2012-04-30 23:59:59')
GROUP BY monthgroup
) a
CROSS JOIN
jb_users b
--
ORDER BY a.monthgroup, b.id #for clarity's sake
その結果:
monthgroup
これで、とすべての の組み合わせができましたが、時間範囲より遅いid
ユーザーを含めたくないため、句signup_time
に最初の条件を導入してそれらを除外します。WHERE
SELECT
a.monthgroup,
b.*
FROM
(
SELECT MONTH(FROM_UNIXTIME(modified_time)) AS monthgroup
FROM jb_resumes
WHERE modified_time BETWEEN
UNIX_TIMESTAMP('2012-03-01 00:00:00')
AND UNIX_TIMESTAMP('2012-04-30 23:59:59')
GROUP BY monthgroup
) a
CROSS JOIN
jb_users b
WHERE
b.signup_time < UNIX_TIMESTAMP('2012-04-30 23:59:59')
--
ORDER BY a.monthgroup, b.id #for clarity's sake
その結果:
通知id
1
は除外されました。これで、次の方法で比較できますLEFT JOIN
。
SELECT
a.monthgroup,
b.*,
c.*
FROM
(
SELECT MONTH(FROM_UNIXTIME(modified_time)) AS monthgroup
FROM jb_resumes
WHERE modified_time BETWEEN
UNIX_TIMESTAMP('2012-03-01 00:00:00')
AND UNIX_TIMESTAMP('2012-04-30 23:59:59')
GROUP BY monthgroup
) a
CROSS JOIN
jb_users b
LEFT JOIN
jb_resumes c ON
b.id = c.user_id
AND a.monthgroup = MONTH(FROM_UNIXTIME(modified_time))
WHERE
b.signup_time < UNIX_TIMESTAMP('2012-04-30 23:59:59')
--
ORDER BY a.monthgroup, b.id #for clarity's sake
その結果:
ここでは、ユーザーが履歴書の変更を行い、変更が値の月内に発生したLEFT JOIN
という条件で ing しています。ユーザーがその月に履歴書を変更していない場合、はテーブルの値を返します。条件が満たされないユーザーが欲しいので、2 番目の条件を句に入れる必要があります。jb_resumes
monthgroup
LEFT JOIN
NULL
WHERE
SELECT
a.monthgroup,
b.*,
c.*
FROM
(
SELECT MONTH(FROM_UNIXTIME(modified_time)) AS monthgroup
FROM jb_resumes
WHERE modified_time BETWEEN
UNIX_TIMESTAMP('2012-03-01 00:00:00')
AND UNIX_TIMESTAMP('2012-04-30 23:59:59')
GROUP BY monthgroup
) a
CROSS JOIN
jb_users b
LEFT JOIN
jb_resumes c ON
b.id = c.user_id
AND a.monthgroup = MONTH(FROM_UNIXTIME(modified_time))
WHERE
b.signup_time < UNIX_TIMESTAMP('2012-04-30 23:59:59')
AND c.user_id IS NULL
--
ORDER BY a.monthgroup, b.id #for clarity's sake
その結果:
最後に、monthgroup
フィールドでグループ化し、 COUNT()
andGROUP_CONCAT()
関数を配置できます。
SELECT
COUNT(*) AS cnt,
GROUP_CONCAT(b.id ORDER BY b.id) AS user_ids,
a.monthgroup
FROM
(
SELECT MONTH(FROM_UNIXTIME(modified_time)) AS monthgroup
FROM jb_resumes
WHERE modified_time BETWEEN
UNIX_TIMESTAMP('2012-03-01 00:00:00')
AND UNIX_TIMESTAMP('2012-04-30 23:59:59')
GROUP BY monthgroup
) a
CROSS JOIN
jb_users b
LEFT JOIN
jb_resumes c ON
b.id = c.user_id
AND a.monthgroup = MONTH(FROM_UNIXTIME(modified_time))
WHERE
b.signup_time < UNIX_TIMESTAMP('2012-04-30 23:59:59')
AND c.user_id IS NULL
GROUP BY
a.monthgroup
ORDER BY
a.monthgroup
望ましい結果が得られます。