2011-01-19 15 views
0

IN句にカンマ区切りの文字列を返すサブクエリを使用しようとしています。返されるカンマ区切りの文字列の数が無効です。

次の方法:

SELECT p.person_id, g.name || '>>' || p.firstname || ' ' || p.lastname as GROUP_PATH 
FROM PERSON p 
LEFT JOIN GROUP g ON (
    g.group_id = p.group_id 
) 
WHERE p.person_id IN ( 
    SELECT person_ids FROM other WHERE other_id = :OTHER_ID 
) 
ORDER BY lower(GROUP_PATH) 

そして、私は次のようなエラーになっています:

ORA-01722: invalid number.

が良いこれを行う方法、あるいは可能性はありますか?

+0

3つのテーブルすべてに対してテーブル定義(特にidカラムタイプ)を表示できますか? ':other_id'はどのように定義されていますか?あなたは数字だけを持っていると思うvarcharに数値列を結合しているかもしれませんし、数値にしか一致しないかもしれませんし、関連性がないと思っている数値以外の値にトリップしています。 –

+0

最初のクエリが間違っていたことに気付きました。私はそれを更新しました。 – Kel

+0

'other'の' person_ids'はコンマ区切りのリストですか?もしそうなら、それは 'IN'節では動作しません。文字列をコレクションとして解析し、そのコレクションをクエリで使用する必要があります。しかし、最初はリレーショナルデータベースにカンマで区切ったキーのリストを格納してはいけませんので、おそらくデータモデルを修正したいと考えています。 –

答えて

4

最も明白な説明は、あなたが文字列で数学をやろうとしているということです...

The attempted conversion of a character string to a number failed because the character string was not a valid numeric literal. Only numeric fields or character fields containing numeric data may be used in arithmetic functions or expressions. Only numeric fields may be added to or subtracted from dates.

http://ora-01722.ora-code.com/

更新#1:

あなたの説明は私を心配:

I am trying to use a subquery that returns a comma delimited string in a IN clause.

Y ではないは、カンマで区切られた文字列を返します(g.group_idが文字列で、カンマ区切りの文字列が必要な場合を除く)。必要に応じて行数を増やす必要があります(とにかく1,000未満)。

更新#2:

SELECT * 
FROM (
    SELECT 1 AS FOO_ID FROM DUAL UNION SELECT 2 FROM DUAL UNION SELECT 3 FROM DUAL 
) FOO; 

FOO_ID     
---------------------- 
1      
2      
3 

あなたはこれを行うことができます:

ちょうどそれを明確にする

SELECT * 
FROM (
    SELECT 1 AS FOO_ID FROM DUAL UNION SELECT 2 FROM DUAL UNION SELECT 3 FROM DUAL 
) FOO 
WHERE FOO_ID IN (1, 2); 

FOO_ID     
---------------------- 
1      
2 

をしかしないこの:

SELECT * 
FROM (
    SELECT 1 AS FOO_ID FROM DUAL UNION SELECT 2 FROM DUAL UNION SELECT 3 FROM DUAL 
) FOO 
WHERE FOO_ID IN ('1,2'); 

SQL Error: ORA-01722: invalid number 

数字1を文字列'1,2'と比較することはできません。別名GROUP_PATHを参照するために、あなたはORDER BY句で参照する前に別名が定義されているネストされたサブクエリを使用する必要がありますする必要があり、最低でも

SELECT * 
FROM (
    SELECT 1 AS FOO_ID FROM DUAL UNION SELECT 2 FROM DUAL UNION SELECT 3 FROM DUAL 
) FOO 
WHERE FOO_ID IN (
    SELECT 1 AS FOO_ID FROM DUAL UNION SELECT 2 FROM DUAL 
); 

FOO_ID     
---------------------- 
1      
2 

SELECT * 
FROM (
    SELECT 1 AS FOO_ID FROM DUAL UNION SELECT 2 FROM DUAL UNION SELECT 3 FROM DUAL 
) FOO 
WHERE FOO_ID IN (
    SELECT '1,2' AS FOO_ID FROM DUAL 
); 

SQL Error: ORA-01722: invalid number 
+0

私は、サブクエリを照会して結果(カンマ区切り)をIN節に貼り付けるだけでうまくいきます。それについての説明は? – Kel

+1

「10,20,30」を得るとしましょう。あなたはそれで何をしていますか? 'g.group_id IN(10,20,30)'(3つの数字)または 'g.group_id IN('10,20,30 ')'(1つの文字列)? –

+0

私は間違ったクエリを書き直したことに気付きました。今すぐチェックしてください。 私はgroup_idsではなく、複数のperson_idsを取得するはずです。 – Kel

2

:サブクエリは、同様の規則に従ってください。それは現実的にOTHERテーブル内PERSON_IDS列が値のカンマ区切りのリストである場合は、お使いのINリストが何をしたいんだろうされていませんORA-01722エラーの原因となったが、それが問題である

SELECT group_id, group_path 
    FROM (SELECT g.group_id, 
       g.name || '>>' || p.firstname || ' ' || p.lastname as GROUP_PATH 
      FROM PERSON p 
       LEFT JOIN GROUP g ON (
         g.group_id = p.group_id 
       ) 
     WHERE p.person_id IN ( 
       SELECT person_ids FROM other WHERE other_id = :OTHER_ID 
       ) 
ORDER BY lower(GROUP_PATH) 

ていません期待する。スカラー文字列(コンマを含む)を複数のPERSON_ID値のコレクションに変換する必要があります。これにはさまざまなアプローチがありますが、Tom Kyteにはvariable IN listを使用する1つの例があります。トムのIN_LIST関数をコピーするとすれば、

SELECT group_id, group_path 
    FROM (SELECT g.group_id, 
       g.name || '>>' || p.firstname || ' ' || p.lastname as GROUP_PATH 
      FROM PERSON p 
       LEFT JOIN GROUP g ON (
         g.group_id = p.group_id 
       ) 
     WHERE p.person_id IN ( 
       SELECT column_value 
       FROM TABLE(SELECT in_list(person_ids) 
           FROM other 
          WHERE other_id = :OTHER_ID) 
       ) 
ORDER BY lower(GROUP_PATH) 
+0

ご返信ありがとうございます。私はちょうど私が間違ってクエリを書いて気づいた。カンマ区切りのグループIDの文字列を取得する代わりに、カンマ区切りのIDを取得しています。 – Kel

+0

@Kel - 一致するようにクエリを編集しました –

関連する問題