(PHPとMySQL) ちょっと難しいSQLお願いします。


質問は長いので http://d.hatena.ne.jp/esecua/20060320 をご覧ください。

よろしくお願いします。

回答の条件
  • 1人3回まで
  • 登録:2006/03/21 00:26:44
  • 終了:2006/03/25 11:06:05

ベストアンサー

id:Sampo No.2

Sampo回答回数556ベストアンサー獲得回数1042006/03/21 02:51:40

ポイント34pt

dayの列を数値化できれば、基準日2006/1/2との比較が容易になるんですよね。数値化はこうしましょう。

substring_index( day, '/', 1 ) * 10000 + substring_index( substring_index(day, '/', 2), '/', -1 ) * 100 + substring_index(day, '/', -1)

実際のレコード抽出は

select * from hatena where name='hate' and 20060102 <= substring_index( day, '/', 1 ) * 10000 + substring_index( substring_index(day, '/', 2), '/', -1 ) * 100 + substring_index(day, '/', -1)

で基準日以降のものを

select * from hatena where name='hate' and 20060102 > substring_index( day, '/', 1 ) * 10000 + substring_index( substring_index(day, '/', 2), '/', -1 ) * 100 + substring_index(day, '/', -1)

で基準日以前のものを抽出できます。

その他の回答(3件)

id:kuippa No.1

くいっぱ回答回数1030ベストアンサー獲得回数132006/03/21 02:17:32

ポイント30pt

すこし条件がわかりにくかったので、要望と違うようであればコメントをつけてください。


行いたいことはnameがhateで2006年1月2日以降で、いつデータが入力されたか確かめたいです。

おおよそ1月2日以降というだけで1月3日とは限らないので2日以降のレコードを一つのみ取得し、

dayに入っている値から日付を取得したいと思っています。


まず、これはこういうことですか??

SELECT max(day) FROM hatena WHERE name = 'hate' and day > '2006/1/2' ORDER BY `number` DESC

もしくは、

SELECT day FROM hatena WHERE name = 'hate' and day > '2006/1/2' ORDER BY `number` DESC Limit 0,1

というようなことでしょうか?

numberが最大のものをもってきたいのであれば、

SELECT max(number),day FROM hatena WHERE name = 'hate' and day > '2006/1/2' Group by day ORDER BY `number` DESC

というような使い方もできるかとおもいます。

(* ´¬`)。oO(日付の指定での比較は、時間単位まで見るので…要件にあわせてキャストの必要があるような気がしますが)




逆に1月2日以前にいつデータが入力されたのかも知りたいので以前のレコードも

1つ取得しdayの値から日付を割り出したいと考えています。

これは、

SELECT day FROM hatena WHERE name = 'hate' and day <= '2006/1/2' ORDER BY `number` DESC

ということですよね??



この二つの式を合わせて取得したいということですか??

でしたら、二つ同時にはとれないので、

....mySQL4.1以前なら。


SELECT 
	max(tbl1.number),
	tbl1.day,
	max(tbl2.number),
	tbl2.day 
FROM hatena tbl1,
	 hatena tbl2 
WHERE 
	tbl1.name = tbl2.name
	and tbl1.name = 'hate' 
	and tbl1.day > '2006/1/2' 
	and tbl2.day <= '2006/1/2' 
GROUP BY 
	tbl1.day,tbl2.day
ORDER BY tbl1.number DESC 
LIMIT 0,1


こんなんですかね? mySQLのverが5(?)以上でサブクエリが使えるならば、それこそこんなのでどうでしょうか。

SELECT 
	*
FROM 
	(SELECT * FROM hatena WHERE name = 'hate' and day > '2006/1/2' ORDER BY `number` DESC Limit 0,1),
	(SELECT * FROM hatena WHERE name = 'hate' and day <= '2006/1/2' ORDER BY `number` DESC Limit 0,1)

ちょっと空書きなので、エラーを吐くかもしれません。不都合があれば指摘してください。

id:esecua

ごめんなさい、質問に間違えがありました。私のミスです。

dayに入っているデータは実際には 2006/3/21 PM12:32 のように日付と時間が入力されていました。すいません。そうなってしまうと SELECT max(day) FROM hatena WHERE name = 'hate' and day > '2006/1/2' ORDER BY `number` DESC ではちょっと無理なようです。

以上の条件で実装するにはどうしたらいいのでしょうか?よろしくお願いします。

2006/03/21 02:35:05
id:Sampo No.2

Sampo回答回数556ベストアンサー獲得回数1042006/03/21 02:51:40ここでベストアンサー

ポイント34pt

dayの列を数値化できれば、基準日2006/1/2との比較が容易になるんですよね。数値化はこうしましょう。

substring_index( day, '/', 1 ) * 10000 + substring_index( substring_index(day, '/', 2), '/', -1 ) * 100 + substring_index(day, '/', -1)

実際のレコード抽出は

select * from hatena where name='hate' and 20060102 <= substring_index( day, '/', 1 ) * 10000 + substring_index( substring_index(day, '/', 2), '/', -1 ) * 100 + substring_index(day, '/', -1)

で基準日以降のものを

select * from hatena where name='hate' and 20060102 > substring_index( day, '/', 1 ) * 10000 + substring_index( substring_index(day, '/', 2), '/', -1 ) * 100 + substring_index(day, '/', -1)

で基準日以前のものを抽出できます。

id:kuippa No.3

くいっぱ回答回数1030ベストアンサー獲得回数132006/03/21 03:56:11

ポイント25pt

二回目の回答です。


MySQL 編13 - 数値関数、余り、四捨五入、切り捨て、切り上げ、数値書式 - SAK Streets


時間は入っていますが、時間そのものを参照する必要が無い場合は、

	and tbl1.day >=  to_days('2006-01-03 00:00:00')
	and tbl2.day <=  to_days('2006-01-02 23:59:59')

のようにしてしまうのもありですよ。

参照先を数値に変換して比較するのも”あり”ですが、母数が多くなるとその分、変換が増えますので、場合によっては絞込みの方を日付になおしちゃったほうが楽チンだったりします。




あと、前回回答した、

SELECT 
	*
FROM 
	(SELECT * FROM hatena WHERE name = 'hate' and day > '2006/1/2' ORDER BY `number` DESC Limit 0,1),
	(SELECT * FROM hatena WHERE name = 'hate' and day <= '2006/1/2' ORDER BY `number` DESC Limit 0,1)

これですが

SELECT 
	*
FROM 
	(SELECT * FROM hatena WHERE name = 'hate' and day > '2006/1/2' ORDER BY `number` DESC Limit 0,1) tb1,
	(SELECT * FROM hatena WHERE name = 'hate' and day <= '2006/1/2' ORDER BY `number` DESC Limit 0,1) tb2

という風に、mySQLは別名をつけてやらないとエラーになったかもしれません。

一応補足しておきます。

id:tadashi0805 No.4

tadashi0805回答回数287ベストアンサー獲得回数292006/03/21 08:58:59

ポイント1pt

日付文字列での絞り込みは、以下のようなイメージですよね?

でしたら、OKですよ。

mysql> select * from work1;

+------------------+

| day |

+------------------+

| 2006/01/01 00:00 |

| 2006/01/02 00:00 |

| 2006/01/03 00:00 |

| 2006/01/04 00:00 |

| 2006/01/05 00:00 |

+------------------+

5 rows in set (0.06 sec)

mysql> select * from work1 where day > '2006/01/04';

+------------------+

| day |

+------------------+

| 2006/01/04 00:00 |

| 2006/01/05 00:00 |

+------------------+

2 rows in set (0.28 sec)

MySQLのselect文のwhere区で、文字列の大小比較時に、指定文字列の方が短い場合、その長さまでの分で比較が行われれます。

http://dev.mysql.com/doc/refman/4.1/ja/select.html

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません