• ベストアンサー

A~B にデータがある人以外の人をHITさせる

顧客検索で、ある期間内に来店がない人を検索しようとしていますが、全然いい手が思い浮かびません。 具体的には、 以下テーブルにて、 CREATE TABLE raiten (m_id char(8), dt date); insert into raiten values ("a01", '2004-07-01'), ("a01", '2004-08-02'), ("a01", '2004-09-01'), ("a01", '2004-10-01'), ("a02", '2004-07-02'), ("a02", '2004-10-10'), ("a03", '2004-07-10'), ("a03", '2004-11-01'), ("a03", '2004-12-01'), ("a04", '2004-07-01'), ("a04", '2005-07-02'), ("a05", '2004-07-01'), ("a05", '2004-08-02'), ("a06", '2004-09-02'), ("a07", '2004-06-10'), ("a07", '2004-07-15'), ("a07", '2004-09-02'), ("a08", '2004-07-15'), ("a09", '2004-07-05'), ("a09", '2004-07-15'), ("a09", '2004-07-30'), ("a09", '2004-08-15'), ("a09", '2004-09-15'), ("a09", '2004-10-15'), ("a10", '2004-07-15'), ("a10", '2004-07-06'), ("a10", '2004-09-15'); 2004年08月に来店がない人を検索したいのです。 (2004-08-01 ~ 2004-08-31 まで) 来店がある人ならばすぐ出るのですが、 来店がない人は、その期間来店がないが他の期間に来店があるため、うまくデータが出てこないのが現状です。 8月に来店があるのは a01,a05,a09 の三人なので、 それ以外が出てくるようにはできないでしょうか。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.6

こんばんは。 補足、拝見しました。 なるほど!!その方がいいですね。 BETWEENを使う方がかっこいいかも・・・? では頑張ってください。 (^^ゞ

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (5)

回答No.5

こんにちは。 ちょっとベタでした・・・。 SELECT m_id, SUM(CASE DATE_FORMAT(dt, '%Y/%m') WHEN '2004/08' THEN 1 ELSE 0 END) AS cnt FROM raiten GROUP BY m_id HAVING cnt = 0 これかな? (^^ゞ

moon_night
質問者

お礼

さらにありがとうございます! こちらの構文でもそのままで想定した結果が得られました。 こちらのほうが若干シンプルかな? それにしても副問い合わせがなくても何とかなるんですね^^ 何度もありがとうございました!!

moon_night
質問者

補足

ちなみに、日単位でデータを出すには SELECT m_id, SUM(CASE WHEN ('2004-08-01' <= dt and dt <= '2004-08-31') THEN 1 ELSE 0 END) AS cnt FROM raiten GROUP BY m_id HAVING cnt = 0 で出てきました。

全文を見る
すると、全ての回答が全文表示されます。
回答No.4

こんにちは。 すみません・・・、ちょっと(かなり?)勘違いしてました・・・。 テンポラリーテーブルを使用しても、副問い合わせが使えないのでつらいですね。 というわけで・・・、 SELECT m_id, COUNT(m_id) AS cnt1, SUM(CASE DATE_FORMAT(dt, '%Y/%m') WHEN '2004/08' THEN 0 ELSE 1 END) AS cnt2 FROM raiten GROUP BY m_id HAVING cnt1 = cnt2 m_idごとの出現回数と、m_idごとで指定月以外の出現回数合計を比較して、同じだったら指定月には来店していない・・・、という事ですが・・・。 これまた、動くかどうかはわかりません・・・。 (^^ゞ

moon_night
質問者

お礼

何度もありがとうございます。 テストした結果、想定通りの結果になりました! 構文はそのまま使えました。 ありがとうございました!

全文を見る
すると、全ての回答が全文表示されます。
回答No.3

こんにちは。 副問い合わせが使えないのは、やっぱり厳しいですね・・・。 以下、ちょっとインチキっぽいですが、 SELECT m_id, CASE DATE_FORMAT(dt, '%Y/%m') WHEN '2004/08' THEN '0' ELSE '1' END AS 条件 FROM raiten GROUP BY m_id, 条件 HAVING 条件 = '1' テストしてない(MySQLの構文がわかってない・・・)ので、動かないかも知れませんが・・・、 考え方としてはあってると思います。 後はMySQLに詳しい人にお任せします・・・。 (^^ゞ

moon_night
質問者

お礼

ありがとうございます。 テストをいたしましたが、a01 ~ a10 の全てのデータがHITしてしまいます。 確かにやりたいことはわかるのですが、該当顧客のデータがその月以外にも複数あるためにほかの月に反応してうまくデータが引っ張れなかったりします。 別に一文にこだわっているわけではありませんので、実現できる方法が分かればよいのですが、なかなかうまくはいかないようです。 8月にきている人を出すことはできるので、 メンバーの元データから このHITしたデータを消せればできるのでしょうが、、、 やっぱり現状のデータだけでは無理なのですかね。 PHPなどでif文でまわせれば簡単なんだけど、 データが多くて重いだろうから使えないし。

全文を見る
すると、全ての回答が全文表示されます。
  • jurarumin
  • ベストアンサー率34% (190/544)
回答No.2

仮想テーブルを使えばできない事もありません。 仮想テーブルで8月に来店した人のIDを取得して、全体のデータから除外すれば。 例は、イメージですので正しく動作する保障はありません。 (例) Select raiten.m_id From raiten, (Select m_id From raiten Where dt BETWEEN '2004-08-01' AND '2004-08-31' ←日付型に変換する? ) as In_raiten Where raiten.m_id <> In_raiten.raiten Group By raiten.m_id

moon_night
質問者

お礼

ありがとうございます。 テストをいたしましたが全てのデータが出てきてしまいました。 (ただし副問い合わせが使えない関係上、テンポラリテーブルを使用しています。これが原因だと思います。) CREATE TEMPORARY TABLE a SELECT m_id as m,dt as d FROM raiten WHERE dt BETWEEN '2004-08-01' AND '2004-08-31' GROUP BY m; SELECT * FROM raiten,a WHERE m_id <> m GROUP BY m_id;

全文を見る
すると、全ての回答が全文表示されます。
  • helonpa
  • ベストアンサー率38% (108/278)
回答No.1

DBソフトウェアに依存するSQLもありますので、環境を書かれては如何でしょうか。

moon_night
質問者

補足

SQLはMysqlのカテゴリなのでMysqlです。 バージョンは 4.0.21 です。 テストはWin2000serverで運用していて、本番はFreeBSDを使用しています。 ちなみにWin2000serverはPS4を適用しています。 よろしくお願いします。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • A5:SQL Mk-2でテーブルは作れないのか?

    xamppとA5:SQL Mk-2ソフトを組み合わせてます。 phpmyadminでデータベースとテーブルを作ってMk-2でsql文 例としてselecto * from aaa;などは動きます。 しかしMk-2で CREATE TABLE shiire(scode CHAR(4),kosuu INT,sdate CHAR(7)); INSERT INTO shiire VALUES ('A002',35,'2003-04'); INSERT INTO shiire VALUES ('B002',24,'2003-05'); は作れません。phpmyadminのクエリでは作れます。 ご教授ください。

    • ベストアンサー
    • MySQL
  • MySQL初心者

    -mysql CREATE DATABASE testdb; use testdb; CREATE TABLE car_table(id int(10),name varchar(50)); INSERT INTO car_table VALUES (2,'乗用車'); INSERT INTO car_table VALUES (3,'オープンカー'); INSERT INTO car_table VALUES (4,'トラック'); SELECT * FROM car_table; これで間違ってるとは思わないんですが、なぜか ERROR 1049(42000): Unknown database 'testdb・・ とでます。なぜなんでしょうか?全然わかりません。 何かの設定ミスかなにかでしょうか?

    • ベストアンサー
    • MySQL
  • update文の副問い合わせ使用

    2つのテーブルを結合して、片方のテーブルをUpdateしたいが、Update文での結合方法がよくわかりません。 table_a の excode列が更新対象で、table_aのname列とtable_bのname列の等価結合です。 テーブルとデータの例は以下です。 テーブル1:table_a create table table_a (code int(3), name varchar(10), excode int(6)); insert into table_a values (101,'あいう',0),(102,'かきく',0),(103,'たちつ',0),(201,'なにぬ',0),(301,'わをん',0); テーブル2:table_b create table table_b (excode int(6), name varchar(10)); insert into table_b values (500101,'あいう'),(500102,'かきく'),(500103,'たちつ'); 期待する結果は以下です。 SQL> select * from table_a; +------+--------+--------+ | code | name | excode | +------+--------+--------+ | 101 | あいう | 500101 | | 102 | かきく | 500102 | | 103 | たちつ | 500103 | +------+--------+--------+ MySQLバージョンは、5.0です。 よろしくお願いいたします。

  • マテリアライズド・ビューの再計算について

    こんにちは ORACLE のマテビューについて困っています。 マテビューを作成して元となるテーブルを削除し再び作成してデーターを投入した後 マテビューを参照するとテーブルを削除する前の情報が表示されてリフレッシュされません どのようにしたら再作成後に投入したデーターをマテビューで表示させる事ができますでしょうか 【検証】 ◆テーブルの作成 CREATE TABLE TEST_TBL (A CHAR(2), B CHAR(5)); ◆レコードを追加 INSERT INTO TEST_TBL VALUES('01','AAA'); INSERT INTO TEST_TBL VALUES('02','BBB'); INSERT INTO TEST_TBL VALUES('03','CCC'); COMMIT; ◆マテビューの作成 CREATE MATERIALIZED VIEW MV_TEST_TBL REFRESH COMPLETE ON COMMIT AS SELECT * FROM TEST_TBL; ◆マテビューの確認 #1 SELECT * FROM MV_TEST_TBL; 3件表示される (正常) ◆レコードの追加 INSERT INTO TEST_TBL VALUES('04','DDD'); COMMIT; ◆マテビューの確認 #2 SELECT * FROM MV_TEST_TBL; 4件表示される (正常) ◆テーブルの削除 DROP TABLE TEST_TBL CASCADE CONSTRAINTS; ◆テーブルの作成 CREATE TABLE TEST_TBL (A CHAR(2), B CHAR(5)); ◆マテビューの確認 #3 SELECT * FROM MV_TEST_TBL; 4件表示される (期待としては 0件であったが) ※疑問1 テーブルのDROP & CREATE は再計算のトリガーに           ならないのか? ◆レコードの追加 INSERT INTO TEST_TBL VALUES('05','DDD'); COMMIT; ◆マテビューの確認 #4 SELECT * FROM MV_TEST_TBL; 4件表示される  ※期待としては1件だけが表示されてほしかったが 使い方としてはマテビューではなくても普通のビューでもいいのでは と思われるかもしれませんが、元となるテーブルのDROP & CREATE が システム的に発生しますがその際にビューの再作成をしたくないので マテビューを選択しました。

  • postgreSQLでint8で設定された項目にデータを挿入したいのですが、教えて下さい。

    例えば、下記のようなテーブルを作成し、 create table testm ( data1 int8, data2 int8, data3 int8 ); 普通全ての項目に値があれば、1行挿入することができますが、 insert into testm values (1, 2, 3); もし、値がないのに、項目に挿入したい場合は、できるのでしょうか? insert into testm values (1, , 3); 教えて下さい。それが出来なかった場合の対処方法も教えて下さい。

  • PL/pgSQLの使い方

    PL/pgSQLについて質問させてください。 以下のような2つのテーブルAとBがあります。 テーブルA: aid | fall0 | fall1 -----+-------+------- 001 | 0 | 0 002 | 0 | 0 テーブルB: bid | aid | fall --------+-----+------ 000001 | 001 | 0 000002 | 001 | 0 000003 | 002 | 0 000004 | 002 | 0 テーブルAとテーブルBの関係は1:nの関係です。 以下のような2つのことがやりたいです。 テーブルAのfall0,fall1,テーブルBのfallはフラグです。 今、テーブルBのaid=001であるすべての行のfallを0から1に変えたとき、 それに対応するテーブルAの行のfall1が0から1にかわる。またテーブルBのaid=001である少なくとも一つの行のfallを0から1に変えたとき、 それに対応するテーブルAの行のfall0が0から1にかわるようなプログラムを作りたいのですが、なかなかうまくいきません。今aid=001のときをやりましたが、aidは任意のときを想定しています。もし、ご存知の方がいらっしゃいましたら教えていただけないでしょうか? よろしくお願いいたします。以下は自分が書いたプログラムです。 drop table b; drop table a; create table A ( aid text primary key, fall0 integer, fall1 integer ); create table B ( bid text primary key, aid text not null references A(aid), fall integer ); insert into A values ('001',0,0); insert into A values ('002',0,0); insert into A values ('003',0,0); insert into B values ('000001','001',0); insert into B values ('000002','001',0); insert into B values ('000003','002',0); insert into B values ('000004','002',0); /* 関数の定義 */ create function tri_test() returns trigger as ' begin declare aid_rec if old.fall=0 and new.fall=1 then update a set fall1=1 where a.aid = select b.aid from b where b.fall = 1); end if; return new; end; ' language 'plpgsql'; /* トリガーの定義 */ create trigger tri_b after update or insert on b for each row execute procedure tri_test(); /* B テーブルへのデータ操作 */ update b set fall=1 where aid='001';

  • PHP+MYSQL IF文の初歩

    全く初歩の質問で申し訳ございません。 create table test (shohin char(40),uri int(10) ,kai int(10) ,urikai char(40)); insert into test values('りんご',300,200,'黒字'); insert into test values('みかん',500,300,null); insert into test values('ぶどう',null,null,'未入荷'); で 「みかん」のレコードが、uri > kai なら 「みかん」のurikaiを'黒字'にする方法を IF文でどのように書けばよいのかを教えてください。

    • ベストアンサー
    • PHP
  • DB2 create tableコマンドでエラーになる

    現在redhat9にdb2 v8を導入しています。 そこでテーブルを作成したいのですが、エラーとなりうまくいきません。 どこを修正すればテーブルが作成できるのか教えてください。 また、テーブル作成後に値を入れたいのですが、insertについてのコマンドのアドバイスもお願いします。 CREATE TABLE emp (empno INTEGER ,ename CHAR2(10) ,mgp INTEGER,sal NUMERIC(5,2) ,deptn INTEGER); INSERT INTO EMP VALUES(221000,'TAYLOR',220000,880.60,220000); よろしくお願いします。

  • 指定された趣味を持つメンバーがいるグループを抽出するSQL

    グループテーブル、メンバーテーブル、趣味テーブルの3つのテーブルがあります。 あるメンバーはあるグループに属しており、趣味を1つ持っています。 以下がそのSQLです。 CREATE TABLE groups ( g_id int primary key ); CREATE TABLE members ( m_id int primary key , g_id int , h_id int ); CREATE TABLE hobbies ( h_id int primary key, h_name text ); INSERT INTO groups VALUES ( 1 ); INSERT INTO groups VALUES ( 2 ); INSERT INTO groups VALUES ( 3 ); INSERT INTO members VALUES ( 1, 1, 1); INSERT INTO members VALUES ( 2, 1, 3); INSERT INTO members VALUES ( 3, 1, 4); INSERT INTO members VALUES ( 4, 1, 4); INSERT INTO members VALUES ( 5, 2, 1); INSERT INTO members VALUES ( 6, 2, 2); INSERT INTO members VALUES ( 7, 2, 3); INSERT INTO members VALUES ( 8, 3, 2); INSERT INTO members VALUES ( 9, 3, 3); INSERT INTO members VALUES ( 10, 3, 4); INSERT INTO hobbies VALUES ( 1, 'sports' ); INSERT INTO hobbies VALUES ( 2, 'music' ); INSERT INTO hobbies VALUES ( 3, 'book' ); INSERT INTO hobbies VALUES ( 4, 'drive' ); 指定された趣味を持つメンバーがいるグループを抽出するにはどうすればいいでしょうか? 例えば、「読書が趣味なメンバーとドライブが趣味なメンバーがいるグループは?」「グループ1とグループ3」のような感じです。 一応自分で考えてみたのが、以下ですが、これだと趣味の指定が増減すると大きくSQLが変わってしまいます。 もっといいやり方はないでしょうか? 私はPostgreSQL8を使ってますが、汎用的なSQLであれば、そっちの方がいいです。 SELECT distinct m.g_id FROM members m join hobbies h ON m.h_id = h.h_id where h.h_name = 'drive' INTERSECT SELECT distinct m.g_id FROM members m join hobbies h ON m.h_id = h.h_id where h.h_name = 'book';

  • MySQLから取り出したものを3つに分ける

    MySQLに以下のようなSQLを打ちました。 create table table_list( id int, task varchar(255) ); insert into table_list values(1,'ほげほげ1-1'); insert into table_list values(1,'ほげほげ1-2'); insert into table_list values(2,'ほげほげ2-1); insert into table_list values(2,'ほげほげ2-2'); insert into table_list values(3,'ほげほげ3-1'); そして、空のdiv要素が3つあります。 このデータベースからidの数値別に、div要素へtaskの文字列を入れたいのですが、どうすればいいのでしょうか? SQLで「select * from table_list」をやってからtaskを取り出すのか、3回SQLで「select task from table_list where id=1」のようにするのがよろしいんでしょうか?

    • ベストアンサー
    • PHP