AIと戦って、あなたの人生のリスク診断 >>

お世話になります。
SQLで1バイト、2バイト混在データでの切出し方法を教えてください。
例:以下のような混在データから左から6バイトを切出したいです。
123:交通費
1234:通勤費

123:交通費 の場合は、「123:交」の形で6バイト きれいに切出せますが、
1234:通勤費 の場合は、「1234:通」の形で6バイトが「通」にかかってしまっています。
この場合、最後の「通」は無視して、「1234:」で出力されるように
したいのです。
何か良い書き方を教えて下さい。
よろしくお願いいたします。

このQ&Aに関連する最新のQ&A

A 回答 (2件)

こんにちは。



以下の方法で、出来ませんか?
SELECT RTRIM(CONVERT(CHAR(6), SUBSTRING(文字列,1,6)))
    • good
    • 4
この回答へのお礼

回答いただきました皆様へ

お忙しい中、ご相談に乗っていただきありがとうございました。
今回は、回答者No.2さんの回答をORACLE用SQLに見直して解決いたしました。
またよろしくお願い申し上げます。

お礼日時:2007/06/21 23:00

バージョンが無いので分かりませんが


VB6、VBAであれば
こんな感じで

Sub aaa()

Debug.Print Left6("123:交通費")
Debug.Print Left6("1234:通勤費")

End Sub


Function Left6(ByVal vstr As String) As String
'切る位置が全角文字の真中かどうか判定する
If Len(StrConv(LeftB(StrConv(vstr, vbFromUnicode), 6), vbUnicode)) _
= Len(StrConv(LeftB(StrConv(vstr, vbFromUnicode), 5), vbUnicode)) Then
'1バイト前で切ったときに文字数が変わらないのは切った位置が全角文字の後半であるので
'切り位置が正しいと判断する
Left6 = StrConv(LeftB(StrConv(vstr, vbFromUnicode), 6), vbUnicode)
Else '泣き別れのパターン
Left6 = StrConv(LeftB(StrConv(vstr, vbFromUnicode), 5), vbUnicode)
End If
End Function
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q全角空白のTRIMができない・・・

文字列の前後の全角空白を除去するのに
trimが使えると思っていたのですが、できませんでした。
(半角なら取れるのですが・・・)

select trim(' あいうえお ') from dual;

何とか前後の全角空白を除去したいのですが、
何か方法はないでしょうか。

Aベストアンサー

こんな感じ。
select trim(' ' from ' あいうえお ') from dual

第2引数で消したい文字を指定できます。
select rtrim(ltrim(' あいうえお ',' '),' ') from dual

QSQL 全角半角混在の文字列から半角数字のみを抜き出す

以下のようなことを「SQL文のみ」で行いたいのですが、
どなたかご教授のほどお願い致します。

下記のような変換前の文字列があるとします。
それを変換後のような形式にしたいのですが可能でしょうか?
■変換前
→2721111千葉県浦安市3-3-3浦安マンション222

■変換後
→2721111333222

要するに数字だけを抜き出したいのですが
できますでしょうか。

REGEXPのような正規表現は使用できないようです、
oracle9iです。

恐れ入りますが、よろしくお願いします。

Aベストアンサー

数値のみピックアップするのは無理矢理出来ます。

select
replace(translate(:対象文字列,replace(translate(:対象文字列,'0123456789','0'),''),'x'),'x','')
from dual;

*「:対象文字」の部分を格納している項目や変数に読み替えてください。

QMAX値を条件にデータを取得するには?

SQL文で困っています。
ご教授下さい。


下記のようなデータがあった場合、それぞれの区分毎に
年月が最大(最新)のデータを取得したいです。
(実際には1レコードにその他項目があり、それらも取得します。)
<検索対象データ>
区分 年月   金額
-----------------------------
A   200412  600
A   200503  560
B   200311  600
B   200508  1000
B   200504  560
C   200508  400
C   200301  1100


<取得したいデータ>

区分 年月   金額
-----------------------------
A   200503  560
B   200508  1000
C   200508  400

よろしくお願いします。

Aベストアンサー

テーブル名をXXXとすると次のようなSQLでよいと思います。(最善の方法かどうかは自信がないですが)

select B.* from (select 区分, max(年月) as 年月 from XXX group by 区分) As A
inner join XXX as B on A.区分 = B.区分 and A.年月 = B.年月
order by B.区分

QOracle(オラクル)で、日付時刻型の検索方法について

質問させていただきます。
データベースはオラクルを使っていて、
SQL文で、抽出するときにエラーが出て困っています。

日付時刻型が「2005/05/26 19:13:00」という感じで入ってます。
2005/05/26 を抽出したいのですが、
BETWEEN '2005/05/26 00:00:00' AND '2005/05/26 23:59:59'

だと、エラーでできません。
どなた様か、ご教授よろしくお願いしますm(_ _)m

Aベストアンサー

日付検索を行う場合は、以下のように書式を含める必要があります。

col BETWEEN TO_DATE('2005/05/26 00:00:00','YYYY/MM/DD HH24:MI:SS') AND TO_DATE('2005/05/26 23:59:59','YYYY/MM/DD HH24:MI:SS')

ただ、厳密には

col >= TO_DATE('2005/05/26', 'YYYY/MM/DD')
AND
col < TO_DATE('2005/05/27', 'YYYY/MM/DD')

と書くべきでしょうね。

QEXCELの文字列操作で文字数不足の分をスペースで補う方法

EXCELの文字データを取り出す際に以下のような操作を行いたいんですが、方法をご存知の方がいらっしゃいましたら教えていただけませんでしょうか。

既にデータの入力されているセルの文字数が、ある一定数に満たない場合は不足分を半角スペースで補う

【例】文字数を15と指定したとします
セルに入力されたデータ:山田_ 太郎
   ↓
求めたいデータ:山田_ 太郎_ _ _ _ _ _
(山田の後に半角スペースが1、太郎の後に半角スペースが6つ入っていると仮定してください)

※TEXT関数で数値の文字数不足分を0で埋めるということはできたのですが、TEXT関数は数値のみを対象としているようで・・・。
【例】12345 → 000000000012345

よろしくお願いいたします。

Aベストアンサー

A1に「山田 太郎」が入っている場合、
 =LEFTB(A1&REPT(" ",15),15)
と式を立てればOKです。

LEFBは、左側から指定バイト分(半角1バイト・全角2バイト)を抜き出す関数。
REPTは、所定の文字をくり返す関数です。

Q半角英数文字の抽出がしたい。

こんにちは。
SQLで分からない事があります。
大変申し訳ございませんが、ご存知の方おられましたら
アドバイスをよろしくお願い致します。
SQLで無理な場合はPL/SQLでも構いません。

(質問内容)
SELECT文で、カラムに入っている値を半角英字or数字だけ取り出して
SELECTをしたいのですが、どのようにすればよいのでしょうか?

例)カラムに値にABC-!123が設定されている場合、
  ABC123がSELECTできるようにしたい。
 ※カラムには何が設定されているかわかりません。
  (NULLという事は、ありません。)

以上です。
よろしくお願い致します。

Aベストアンサー

PL/SQLでつくってみました。
1文字づつチェックしているので、ちょっとスマートではないかも知れませんが・・・・

create or replace function GET_ALPHA_NUM(STR IN VARCHAR2) return varchar2 is
Result VARCHAR2(300); --結果

STR_TMP VARCHAR2(300); --チェック用の文字列(大文字にして格納)
CHK_CHAR VARCHAR(2); --バッファ
CHK_CHAR_CODE NUMBER;

iLoop NUMBER;

begin
STR_TMP := NLS_UPPER(STR); --大文字にして格納(全角もとりたい場合はさらにTO_SINGLE_BYTE関数をかける)

--1文字ずつチェックする
For iLoop in 1 .. LENGTH(STR) LOOP
CHK_CHAR := SUBSTR(STR_TMP, ILOOP, 1); --チェック文字
CHK_CHAR_CODE := ASCII(CHK_CHAR); --文字のコード

IF CHK_CHAR_CODE >= ASCII('A') AND CHK_CHAR_CODE <= ASCII('Z') THEN
--文字がA~Z
Result := Result || SUBSTR(STR, ILOOP, 1);

ELSIF CHK_CHAR_CODE >= ASCII('0') AND CHK_CHAR_CODE <= ASCII('9') THEN
--文字が1~9
Result := Result || SUBSTR(STR, ILOOP, 1);

END IF;
END LOOP;

return(Result);

end;

PL/SQLでつくってみました。
1文字づつチェックしているので、ちょっとスマートではないかも知れませんが・・・・

create or replace function GET_ALPHA_NUM(STR IN VARCHAR2) return varchar2 is
Result VARCHAR2(300); --結果

STR_TMP VARCHAR2(300); --チェック用の文字列(大文字にして格納)
CHK_CHAR VARCHAR(2); --バッファ
CHK_CHAR_CODE NUMBER;

iLoop NUMBER;

begin
STR_TMP := NLS_UPPER(STR); --大文字にして格納(全角もとりたい場合はさらにTO_SINGLE_BY...続きを読む

QSELECTで1件のみ取得するには?

こんにちわ。
いまORACLE9iを使用している者です。

ACCESSでは
SELECT TOP 1 項目名 FROM テーブル名
ORDER BY 項目名;
で並べ替えたデータ群のうち,先頭の1件だけを
取ることができますが,
ORACLEでそのような機能(SQL)はあるでしょうか?
教えてください。
よろしくお願いします。

Aベストアンサー

order by と rownum を併用する場合は注意が必要です。

[tbl01]
cola | colb
------------
1000 | aaaa
1001 | bbbb

というデータがある場合、
select cola from tbl01 where rownum < 1 order by cola desc;
とすると、「1001」ではなく、「1000」が返されます。
これは、order by の前に rownum < 1 が適用されてしまうからです。

解決するには、
select aaa from (select cola aaa from tbl01 order by cola desc) where rownum = 1;
とすれば良いです。

QUPDATE文でこのような更新はできますか?

(TBL_A)
A1  A2
-----------
1  100
2  200
3  300
4  400
5  500


(TBL_B)
B1  B2
-----------
1  100
3  300
4  400


上記のようなテーブルAとBがあったとして
次のようなUPDATE文を実行することはできますか?
できない場合、SQL1発で更新する他の方法はありますでしょうか?

UPDATE TBL_A A SET
A.A1 = A.A1 + B.B1
A.A2 = A.A2 + B.B2
WHERE EXISTS
(SELECT 'X' FROM TBL_B B WHERE A.A1=B.B1)

【更新後のTBL_A表】
A1  A2
-----------
1  200 <= (*)更新される
2  200
3  600 <= (*)更新される
4  400
5  1000 <= (*)更新される

【やりたいこと】
TBL_A表のA2列のデータにTBL_B表のB2列のデータを加算したい。
その場合の更新条件として「A1がB1に存在している場合のみ」という条件を加えたいのです。

すいませんが、よろしくおねがいします。

(TBL_A)
A1  A2
-----------
1  100
2  200
3  300
4  400
5  500


(TBL_B)
B1  B2
-----------
1  100
3  300
4  400


上記のようなテーブルAとBがあったとして
次のようなUPDATE文を実行することはできますか?
できない場合、SQL1発で更新する他の方法はありますでしょうか?

UPDATE TBL_A A SET
A.A1 = A.A1 + B.B1
A.A2 = A.A2 + B.B2
WHERE EXISTS
(SELECT 'X' FROM TBL_B B WHERE A.A1=B.B1)

【更新後のTBL_A表】
...続きを読む

Aベストアンサー

>次のようなUPDATE文を実行することはできますか?
エラーになり実行できないと思いますがどうですか???
SET文に、
A.A1 = A.A1 + B.B1
と書いても、「B.B1」がなんのことか、DB側には分かりません。

EXISTSはあくまで、「Bに存在する行を」という更新の対象の行を絞る条件にしかならないので、
SET文でBのB1値を使いたいなら連結しなくてはいけません。

副問い合わせにしたらいかがですか?
UPDATE TBL_A A
SET A.A2 =
(SELECT A.A2 + B.B2 FROM TBL_B B
WHERE A.A1 = B.B1)
WHERE EXISTS
(SELECT * FROM TBL_B B WHERE A.A1=B.B1)

こんなかんじです。
ちなみにEXISTS文なりなんなりの「A1がB1に存在している場合のみ」
というWhere句は必要です。
上記のSQLにEXISTS文がない場合、
Bに存在しないAの行(A1が2と5の場合)もUPDATE文の対象となり、
Bとの連結の結果がNULL値になるので、
その行のA2の値がNULLで更新されてしまいます。
NULL値の加算はNULLだからです。
↓以下のようになります。

A1  A2
-----------
1  200
2  Null
3  600
4  800
5  Null

あまり意味がわからないかもしれませんが、
とりあえず、簡単なテーブルでも作って、
試してみてはいかがでしょうか。

>次のようなUPDATE文を実行することはできますか?
エラーになり実行できないと思いますがどうですか???
SET文に、
A.A1 = A.A1 + B.B1
と書いても、「B.B1」がなんのことか、DB側には分かりません。

EXISTSはあくまで、「Bに存在する行を」という更新の対象の行を絞る条件にしかならないので、
SET文でBのB1値を使いたいなら連結しなくてはいけません。

副問い合わせにしたらいかがですか?
UPDATE TBL_A A
SET A.A2 =
(SELECT A.A2 + B.B2 FROM TBL_B B
WHERE A.A1 = B.B1)
WHERE EX...続きを読む

QViewにインデックスは張れますか?

件名の通りなのですが、作成したViewが遅くて困っています。
改善方法としてはViewを作成しないで従来のSQLにインデックスを張って取得する方法にしようかなと考えています。
なにかいい方法はありますか?

Aベストアンサー

Viewの元テーブルに適切なIndexを貼る、ではいけないのですか?

QOracleでの文字列連結サイズの上限

Oracle9iでテーブル内容をスプール出力していますが、カラム単位で余白を削除したい
(トリムをかけたい)ので以下のようにカラムを連結させてスプールしています。
set colsep ','
spool test.csv
select
a ||','||
b ||','||
c
from test_table
spool off

実際の項目数は100以上あり、レコードの最大長も数千バイトになりますが、
各項目にMAXの値を入力して上記スプールを実行したところ、以下のエラーメッセージが
出力されました。
「ORA-01489: 文字列を連結した結果、長さが最大長を超えました」

データを連結した結果の長さが上限を超えたということなのでしょうが、
この最大長はどこで設定されているものなのでしょうか?
また、そもそもスプール出力でトリムが効かないためにこのようなやり方で
出力していますが、他によい方法をご存知の方いましたら教えて下さい。
よろしくお願いします。

Aベストアンサー

>>Code Tipsの内容も実際に試してみたのですが、結局のところ項目を連結させる
>>やり方では4000バイトまでが限度ということだと判断したのですが

4000バイトまでが限度 とは、どのような理由からでしょうか?
以下のSQLで4000バイトオーバーは可能です。(32KBの壁はあります)

既に完成度の高いスクリプトがデバッグ済みで存在するのに
同じものを 1からコーディングするのは、(自分の勉強にはなるとは思いますが) 意味のない行為だと思いますので、
Code Tipsをお勧めしました。

SPOOL HOGE.TXT
SET PAGESIZE 0
SET LINESIZE 32767
SET LONG 40000
SET LONGC 40000
SET TRIMSPOOL ON
SET FEEDBACK OFF
SET VERIFY OFF

SELECT
TO_CLOB('')
|| LPAD('1', 4000,'1')
|| LPAD('2', 4000,'2')
|| LPAD('3', 4000,'3')
|| LPAD('4', 4000,'4')
|| LPAD('5', 4000,'5')
|| LPAD('6', 4000,'6')
|| LPAD('7', 4000,'7')
|| LPAD('8', 4000,'8')
|| LPAD('9', 4000,'9')
|| LPAD('0', 4000,'0')
FROM DUAL
/
SPOOL OFF

>>Code Tipsの内容も実際に試してみたのですが、結局のところ項目を連結させる
>>やり方では4000バイトまでが限度ということだと判断したのですが

4000バイトまでが限度 とは、どのような理由からでしょうか?
以下のSQLで4000バイトオーバーは可能です。(32KBの壁はあります)

既に完成度の高いスクリプトがデバッグ済みで存在するのに
同じものを 1からコーディングするのは、(自分の勉強にはなるとは思いますが) 意味のない行為だと思いますので、
Code Tipsをお勧めしました。

SPOOL HOGE.TXT
SET...続きを読む


人気Q&Aランキング