- ベストアンサー
Null値を無視してユニークにしたい
下記のようなテーブルがあります。 ID aaa bbb 10 A01 11 12 B01 13 A02 14 A03 B02 ・IDは,主キー(レコードの登録時に,IDENTITYで自動的に取得) ・aaa,bbbは,任意のタイミングで入力や編集があるが,ユニーク性を保ちたい ・aaa,bbbの入力に関しては,下記のようなテーブルを作って自動採番にしたい Category Last_No A 03 B 02 (1)データベース側にて,aaa,bbbにユニークインデックスを設定すると, Null値に関しても重複違反になってしまったのですが, これは,そういうものなのでしょうか? (2)ユニークインデックスが設定できない場合に, Null値以外の値が,ユニークである事を保つためには, どうすれば良いのでしょうか? 自動採番だけでなく,編集も有り得るため,悩んでいます。 (編集は,A01-1のように,枝番を付ける場合が多いです) 以上,どなたかご教示願います。
- SQL Server
- 回答数3
- ありがとう数3
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
ユニーク制約でNULLを除くことができないのは、リンクページに書かれている通りです。 「PRIMARY KEY 制約とは異なり、UNIQUE 制約は NULL 値を許容できます。ただし、UNIQUE 制約が適用される他の値と同様に、NULL 値も 1 列に 1 つしか使用できません。 」 代替案はありますが、導入可否はテーブルデザインのガイドラインとレスポンス要求の程度により判断してください。 具体的には「スカラーファンクションを1つ作成して、チェック制約で使う」というものです。 CREATE FUNCTION [dbo].[ISUNIQUE](@aaa varchar(5)) RETURNS int AS BEGIN IF (SELECT COUNT(*) FROM TABLE1 WHERE aaa=@aaa)>1 RETURN 0 RETURN 1 END ALTER TABLE TABLE1 ADD CONSTRAINT [CK_aaa] CHECK (dbo.ISUNIQUE(aaa)=1) こんな感じです。 ユニークフィールドが複合であっても、上記の応用で実現はできます。 (チェック制約に使われた関数は、チェック制約を外さない限りDROPできなくなります) 今回のはいけますが、そもそもチェック制約というのはDELETEのときには働かないことは認識しておいてください。 またここまで踏み込めなければ同じことをトリガやるのもありかと思います(トリガは権限があればオフれるのでそこが違いでしょう)。
その他の回答 (2)
- jamshid6
- ベストアンサー率88% (591/669)
SQL Server 2000だったのですね。 私の認識する限りでは、SQL Server 2005のようにエラーを抑え込むTRY/CATCH構文のようなものは2000にはないので、VBAサイドでOn Error Resume Nextを使ってエラーを抑え込むことになると思います。
お礼
jamshid6様 度々の回答,ありがとうございます。 On Error Resume Nextにてエラーを回避することにより VBA側でエラー番号を取得できました。
- chukenkenkou
- ベストアンサー率43% (833/1926)
>Null値に関しても重複違反になってしまった SQL Serverの独自仕様になっています。
お礼
chukenkenkou様 ありがとうございます。
関連するQ&A
- 'id'を無視して、外部ファイルを読み込むには?
MySQLでデータベースを作成しています。テーブルを以下のように作成しました。 create table table_name ( id MEDIUMINT NOT NULL AUTO_INCREMENT, aaa text, bbb text, ccc text, PRIMARY KEY (id) ); そして、以下のようなファイル(/root/file)を読み込みます。(尚、ファイルはLinux上で作成しました。) [/root/file] a1,b1,c1 a2,b2,c2 a3,b3,c3 そして、データベース上で以下のようなコマンドを実行しました。 load data local infile '/root/file' into table table_name fields terminated by ',' lines terminated by '\n'; すると、以下のような結果が得られます。 +----+-----+-----+------+ | id | aaa | bbb | ccc | +----+-----+-----+------+ | a1 | b1 | c1 | NULL | | a2 | b2 | c2 | NULL | | a3 | b3 | c3 | NULL | +----+-----+-----+------+ 以下のようにテーブルを作り直すことなく、 create table table_name ( aaa text, bbb text, ccc text, id MEDIUMINT NOT NULL AUTO_INCREMENT, PRIMARY KEY (id) ); また、以下のようにファイルを書くことなく、 [/root/file] ,a1,b1,c1 ,a2,b2,c2 ,a3,b3,c3 以下のような結果を出すにはどのようにすればよいのでしょうか。(つまり、自動的に作成される'id'を無視するにはどうすればよいのでしょうか。) +----+-----+-----+-----+ | id | aaa | bbb | ccc | +----+-----+-----+-----+ | 1 | a1 | b1 | c1 | | 2 | a2 | b2 | c2 | | 3 | a3 | b3 | c3 | +----+-----+-----+-----+ よろしくお願い致します。
- ベストアンサー
- MySQL
- テーブル内の一括コピーについて
SQLServer で テーブルAが下記のようにあり ID name subname 25 AAA NULL 28 BBB NULL 31 CCC NULL subnameの欄にIDの値と全く同じものをいれたいのですが どのようにしたらできるでしょうか? ID name subname 25 AAA 25 28 BBB 28 31 CCC 31 ↑結果的にはこうなってほしいのですが よろしくお願いします。
- ベストアンサー
- SQL Server
- Null同士の結合
お力貸してください。 [Table111] データA データB データC Name111 Null 1 5 あああ 2 Null 6 いいい 3 4 7 ううう [Table222] データA データB データC Name222 Null 1 5 AAA 2 Null 6 BBB 3 4 7 CCC Table111とtable222をデータAとデータBとデーターCの3つで結合して 新しいテーブルをつくりたいです。 [TableC] データA データB データC Name111 Nam222 Null 1 5 あああ AAA 2 Null 6 いいい BBB 3 4 7 ううう CCC Nullもデーターとして認識させたいのですが、うまくいきません。 できれば、新しくテーブルを作ったりしたくないです。 お知恵をかしてください。よろしくおねがいします。
- ベストアンサー
- その他(データベース)
- 重複していないレコードの抽出方法について
下記のテーブルでフィールドAとBの関係で矛盾が生じているID 1と2を抜き出すSQLを必要としております。 AとBを合体させて判断しようと試みましたがダメでした。 ご存知の方ご教示いただけると大変助かります。 【テーブル】 ―――――――――― |ID| A |B| ―――――――――― |1 |AAA|B | |2 |AAA|C | |3 |BBB|D | |4 |BBB|D | |5 |CCC|E | |6 |DDD|F | ―――――――――― よろしくお願いします。
- ベストアンサー
- その他MS Office製品
- NULL行の取得について
教えてください。 Aはトランザクションテーブルです。 A 列1 列2 1 1 2 NULL 3 2 Bは種別テーブルです。 B 列1 列2 列3 aaa 1 あああ1 aaa 2 あああ2 aaa 3 あああ3 select A.列1 B.列3 from INNER JOIN B ON ( (A.列2 = B.列2 or A.列2 is null) and B.列1 = 'aaa') 上記のSQLを実行すると、 A.列1が2のような、列2がNULLだと、 1 あああ1 2 あああ1 2 あああ2 2 あああ3 3 あああ2 となってしまいます。 望む形としては、 1 あああ1 2 null 3 あああ2 としたいのですが。。。 何が悪いか、教えていただけませんでしょうか。 お願いします。
- 締切済み
- SQL Server
- SQLについて教えてください
お世話になります。 SQLについて教えてください AテーブルとBテーブルからCテーブルを作成したいのですが、 KEYをキーにAテーブルのIDが1で、YYMMが一番新しい項目(最大の項目)を 取得し、Cテーブル作成したいのですが、どのようにするのでしょうか? Aテーブル Bテーブル Cテーブル KEY ID yymm KEY KEY YYMM AAA 0 200612 AAA AAA 200611 AAA 1 200611 BBB BBB 200611 AAA 1 200609 BBB 0 200611 CCC 1 200611
- ベストアンサー
- SQL Server
- AccessにおいてフィールドがNULLの値を0に変換するには
下記のようなSQLで件数を取得したいと考えています。 テーブルBの件数がNULLの場合、差がNULLになってしまいます。 このような場合、差を0にしたいです。 どのように修正したらよいでしょうか。 SELECT A.ID, (A.件数-B.件数) AS 差 FROM A LEFT JOIN B ON A.ID = B.ID;
- ベストアンサー
- その他(データベース)
- 抽出条件入力用テキストボックスが空白の場合の抽出条件
SQL初心者です。 今あるテーブル(TABLE)に | VALUE_A | VALUE_B | VALUE_C | VALUE_D | ----------------------------------------- | 000 | AAA | AAA | AAA | | 001 | AAA | AAA | BBB | | 002 | AAA | BBB | AAA | | 003 | BBB | BBB | BBB | | 004 | BBB | BBB | NULL | のようなデータが入っているとします。 Web上から VALUE_B VALUE_C VALUE_D に対しそれぞれテキストボックス入力フィールドから値を入力し検索を行うようにしたいのです。 [VALUE_B]=AAA [VALUE_C]=AAA [VALUE_D]=AAA と入力されれば VALUE_A:000 を検索結果として出します。 [VALUE_B]=AAA [VALUE_D]=AAA と入力されれば VALUE_A:000 VALUE_A:002 を検索結果として出します。 [VALUE_B]=AAA だけが入力された場合は VALUE_A:001 VALUE_A:002 VALUE_A:003 を検索結果として出します。 つまり、フォームのテキストボックスに入力された条件で抽出し、入力が無い場合は全件抽出を行いたいのです。 この場合、どのようなSQLを組めばよいのかわかりません。ANDやORだけでは対応できないような気がします。Oracleを始めたばかりということもあり、どのような関数を使えばよいのかもわかりません。どなたかご教授いただけませんでしょうか??よろしくお願いします。
- ベストアンサー
- Oracle
- 分岐SQLを一発のSQLで実現したい
【データベース:SQLServer2005】 SQLのアドバイスを頂きたいです。 【テーブル】 テーブル名:Table1 フィールド名:種類、キー1、キー2 テーブル名:Table2 フィールド名:種類、キー1、キー2 テーブル名:Table3 フィールド名:種類、キー1、キー2 【データ】 Table1 種類、キー1、キー2 001 AAA BBB 001 AAA CCC 001 AAA DDD Table2 種類、キー1、キー2 002 AAA BBB 002 AAA CCC NULL AAA DDD Table3 種類、キー1、キー2 NULL AAA BBB NULL AAA CCC NULL AAA DDD これをUNIONで取得します。 種類、キー1、キー2 001 AAA BBB 001 AAA CCC 001 AAA DDD 002 AAA BBB 002 AAA CCC NULL AAA DDD NULL AAA BBB NULL AAA CCC 実現したいのは、 1)同種類、キー1、キー2のデータで、 種類にNULLが含まれていたら、NULLのデータは取得しない 2)同種類、キー1、キー2のデータで、 種類にNULLしかないデータは、取得する 001 AAA BBB 001 AAA CCC 001 AAA DDD 002 AAA BBB 002 AAA CCC NULL AAA DDD →いる NULL AAA BBB →いらない NULL AAA CCC →いらない ↓結果 001 AAA CCC 001 AAA DDD 002 AAA BBB 002 AAA CCC NULL AAA DDD 上記を実現する為、UNION後のSQLでも構わないので、 一発のSQLで取得する事は可能でしょうか? 有識者の方にご享受頂ければ幸いです。 どうぞ宜しくお願い申し上げます。
- ベストアンサー
- SQL Server
- 最新レコードを抽出し外部結合する方法について
お世話になります。 現在、最新レコードを抽出し外部結合するSQLを考えているのですが、実現できておりません。 実現できるSQLをご存知の方、いらっしゃいましたら情報を頂けますでしょうか。 # 私の使用しているのは、PostgreSQL8.3となります。 実現したい内容は、以下となります。 1.テーブルAから「名前」でグループ化して最新の「更新日付」のレコードを抽出。 2.1の結果とテーブルBを「名前」で結合。 3.テーブルAの「名前」、「点数」、「更新日付」とテーブルBの「判定」を抽出。 ⇒ただしテーブルAに情報がある場合は、テーブルBの判定結果を「0」にして出力。 テーブルA テーブルB ---------------------------- ----------------------- 名前| 点数| 更新日付 名前 | 判定 ---------------------------- ----------------------- AAA 98 2011/4/1 AAA 0 AAA 60 2011/4/3 BBB 1 BBB 70 2011/4/2 CCC 1 BBB 35 2011/4/4 DDD 1 DDD 98 2011/4/1 EEE 0 EEE 47 2011/4/5 FFF 0 GGG 80 2011/4/6 GGG 1 【出力結果】 --------------------------------------------- 名前 | 点数 | 更新日付 | 判定 --------------------------------------------- AAA 60 2011/4/3 0 BBB 35 2011/4/4 0(1⇒0に変更) CCC NULL NULL 1 DDD 98 2011/4/1 0(1⇒0に変更) EEE 47 2011/4/5 0 FFF NULL NULL 0 GGG 80 2011/4/6 0(1⇒0に変更) お手数お掛け致しますが、ご教示のほどよろしくお願い致します。
- ベストアンサー
- PostgreSQL
お礼
jamshid6様 昨日の質問に引き続き,ご回答いただきましてありがとうございます。 ご回答いただいた内容を試し,aaaフィールドに 重複するレコードが登録出来ないことを確認しました。 ですが,これを下記のように利用しようとしたところで, 躓いてしまいました。 1回目の実行で,aaa=A04のレコードが正常に登録された後, 2回目の実行で,制約違反で発生するエラーをトラップしたいのですが, 「INSERTステートメントはCOLUMN CHECKで,制約'CK_aaa'と矛盾しています。」 とのエラー表示となってしまい,処理が中断してしまいます。 クエリアナライザで, insert TABLE1 values('A04','B03') print @@error として,@@errorにて547と返ってくる事を確認しているのですが, どこが間違っているのでしょうか? ●SQL SERVER 2000のストアド CREATE PROCEDURE Strd_Test_Add ( @aaa varchar(5), @bbb varchar(5), @rowcount int output, @err int output ) AS set nocount on begin BEGIN TRANSACTION insert TABLE1 (aaa,bbb) values(@aaa,@bbb) select @rowcount=@@rowcount ,@err=@@error if @err<>0 goto err COMMIT TRANSACTION end return err: ROLLBACK TRANSACTION return GO ●Excel2003のVBA Private Sub btn1_Click() Set dbCN = New ADODB.Connection dbCN.Open "Provider=SQLOLEDB;" _ & "Data Source=*****;" _ & "Initial Catalog=DB_Test;" _ & "User ID=sa;Password=" Set dbCOM = New ADODB.Command dbCOM.ActiveConnection = dbCN dbCOM.CommandType = adCmdStoredProc dbCOM.CommandText = "Strd_Test_Add" dbCOM.Parameters.Refresh dbCOM.Parameters("@aaa") = "A04" dbCOM.Parameters("@bbb") = "B03" dbCOM.Execute MsgBox dbCOM.Parameters("@rowcount").Value _ & vbCrLf & dbCOM.Parameters("@err").Value Set dbCOM = Nothing End Sub