- PR -

売れなかった(存在しないレコード)製品名の抽出方法は?

1
投稿者投稿内容
コング
会議室デビュー日: 2007/07/21
投稿数: 2
投稿日時: 2007-07-21 14:00
1月9日に新宿で売れなかった果物名を抽出したい。
下記のDBでは2と4が売れているので りんご と メロン を抽出したいのですが
差集合のサンプルではうまくいきません。クエリの方法を教えてください。
PHP 4.4.7
MySQL 5.0.41
===============対象のDBは以下のとおり===============
<?php
mysql_query("DROP TABLE IF EXISTS tbl_A, tbl_B") or die(mysql_error());
$sql="CREATE TABLE tbl_A (
hinban int(11) NOT NULL ,
hinmei varchar(16) NOT NULL default '',
tanka int NOT NULL default '0',
PRIMARY KEY (hinban)
) TYPE=MyISAM COMMENT=''" ;
mysql_query($sql, $connection) or die(mysql_error());
$info.="CREATE TABLE tbl_A <br>";
$sql="CREATE TABLE tbl_B (
hinban int(11) NOT NULL ,
hizuke date NOT NULL default '0000-00-00',
kosuu int NOT NULL default '0',
basho varchar(16) NOT NULL default '',
uriage int NOT NULL default '0'
) TYPE=MyISAM COMMENT=''" ;
mysql_query($sql, $connection) or die(mysql_error());
if ($sql){$info.="CREATE TABLE tbl_B <br>";}
$arr_a[0] =array("1","りんご","60");
$arr_a[1] =array("2","バナナ","50");
$arr_a[2] =array("3","メロン","70");
$arr_a[3] =array("4","かき","40");
for ($g=0;$g<count($arr_a);$g++){
$sql="INSERT INTO tbl_A(hinban,hinmei,tanka) VALUES('".$arr_a[$g][0]."','".$arr_a[$g][1]."','".$arr_a[$g][2]."')";
mysql_query($sql) or die(mysql_error());
$info.=$sql."INSERT tbl_A <br>";
}
$arr_a[0] =array("1","2007-01-09","25","神田");
$arr_a[1] =array("2","2007-01-09","18","新宿");
$arr_a[2] =array("3","2007-01-09","23","神田");
$arr_a[3] =array("4","2007-01-09","18","新宿");
$arr_a[4] =array("1","2007-01-09","23","渋谷");
$arr_a[5] =array("2","2007-01-09","28","新宿");
$arr_a[6] =array("3","2007-01-09","12","神田");
$arr_a[7] =array("4","2007-01-09","10","渋谷");
$arr_a[8] =array("1","2007-01-10","28","新宿");
$arr_a[9] =array("2","2007-01-10","32","渋谷");
for ($g=0;$g<count($arr_a);$g++){
$sql="INSERT INTO tbl_B(hinban,hizuke,kosuu,basho) VALUES('".$arr_a[$g][0]."','".$arr_a[$g][1]."','".$arr_a[$g][2]."','".$arr_a[$g][3]."')";
mysql_query($sql) or die(mysql_error());
}
忠犬
大ベテラン
会議室デビュー日: 2006/05/01
投稿数: 109
投稿日時: 2007-07-21 18:25
SQL部分を含むphpのコードをそのまま提示して、「後は、回答者側で解析して」と
いうことですか?

>差集合のサンプルではうまくいきません

どういうクエリを実行して、どううまく行かなかったのかを書くのがマナーだと思い
ますが?

MySQL 5.0以降なので、サブクエリが使えます。
3パターンの例を示しますから、どれが効率的かは、Explain等で自分で試してみて
ください。

(例1)not existsを使用
コード:
select *
 from tbl_A
 where not exists
   (select * from tbl_B
     where tbl_A.hinban=tbl_B.hinban
       and hizuke='2007-01-09' and basho='新宿')



(例2)not inを使用
コード:
select *
 from tbl_A
 where hinban not in(select hinban from tbl_B
                      where hizuke='2007-01-09' and basho='新宿')



(例3)left joinを使用
コード:
select A.*
 from tbl_A as A left join tbl_B as B
 on A.hinban=B.hinban and B.hizuke='2007-01-09' and B.basho='新宿'
 where B.hinban is null



MySQLはjoinの実装が早くから行なわれ、サブクエリは4.1になってようやく実装
されたという背景からか、joinで書いた方がインデクスを有効利用される傾向が
あるようです。
コング
会議室デビュー日: 2007/07/21
投稿数: 2
投稿日時: 2007-07-22 08:42
忠犬さんありがとうございます。
3つのケースともうまくいきました。
>どういうクエリを実行して、どううまく行かなかったのかを書くのがマナーだと思い
>ますが?
今後気をつけます。
うまくいかなかったSQLは、
select tbl_A.hinmei from tbl_A left join tbl_B
on tbl_B.hizuke = '2007-01-09' and tbl_B.basho = '新宿' where tbl_B.hinban is null

select tbl_A.hinmei  from tbl_A where not exists 
(select hinban from tbl_B where hizuke = '2007-01-09' and basho='新宿')
ですが、どちらともand tbl_A.hinban=tbl_B.hinbanの条件がないのが
間違いでした。
存在しないレコード内容の条件をAND記述することはできないと
思い込んでいました。(目からうろこ)

1

スキルアップ/キャリアアップ(JOB@IT)