Oracle中in子句中返回的逗号分隔字符串的数目无效
我试图使用在in子句中返回逗号分隔字符串的子查询 方法如下:Oracle中in子句中返回的逗号分隔字符串的数目无效,oracle,subquery,in-clause,ora-01722,Oracle,Subquery,In Clause,Ora 01722,我试图使用在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 WHE
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:无效号码
有没有更好的方法,甚至是可能的 最明显的解释是,你试图用一个字符串做数学题 试图转换的文件 将字符串转换为数字失败 因为字符串不是一个 有效的数字文字。只有数字 包含 数字数据可用于算术运算 函数或表达式。只有数字 字段可以加或减 从日期开始 更新#1: 你的描述让我担心: 我正在尝试使用一个子查询 返回以逗号分隔的字符串 在第条中 子查询不应返回逗号分隔的字符串(除非
g.group\u id
是字符串并且需要逗号分隔的字符串)。您必须根据需要检索尽可能多的行中的单个项(无论如何少于1000行)
更新#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'
进行比较。子查询遵循类似的规则:
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
最明显的解释是你试图用一个字符串来做数学 试图转换的文件 将字符串转换为数字失败 因为字符串不是一个 有效的数字文字。只有数字 包含 数字数据可用于算术运算 函数或表达式。只有数字 字段可以加或减 从日期开始 更新#1: 你的描述让我担心: 我正在尝试使用一个子查询 返回以逗号分隔的字符串 在第条中 子查询不应返回逗号分隔的字符串(除非
g.group\u id
是字符串并且需要逗号分隔的字符串)。您必须根据需要检索尽可能多的行中的单个项(无论如何少于1000行)
更新#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'
进行比较。子查询遵循类似的规则:
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
至少,为了引用别名
GROUP\u PATH
,在order BY子句中引用别名之前,需要使用定义别名的嵌套子查询。这实际上并没有导致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)
如果OTHER
表中的PERSON\u id
列是一个以逗号分隔的值列表,则您的in列表将不会达到预期效果。您需要将标量字符串(其中碰巧有逗号)转换为某种多个人ID值的集合。有多种方法可以做到这一点,Tom Kyte举了一个使用。假设您复制Tom的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)
至少,为了引用别名
GROUP\u PATH
,在order BY子句中引用别名之前,需要使用定义别名的嵌套子查询。这实际上并没有导致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)
如果OTHER
表中的PERSON\u id
列是一个以逗号分隔的值列表,则您的in列表将不会达到预期效果。您需要将标量字符串(其中碰巧有逗号)转换为某种多个人ID值的集合。有多种方法可以做到这一点,Tom Kyte举了一个使用。假设您复制Tom的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)
当我只查询子查询并将结果(逗号分隔)粘贴到IN子句中时,效果很好。有什么解释吗?假设你得到了
'10,20,30'
。你用它做什么g.group\u id IN(10,20,30)
(三个数字)或g.group\u id IN('10,20,30')
(一个字符串)?我注意到我重写了错误的查询。现在就去看看。我应该得到多个人ID,而不是团体ID。这并不重要;多个ID是否作为字符串返回?是的,我会这样说,因为person_id列的类型是varchar2。当我只查询子查询并将结果(以逗号分隔)粘贴到IN子句中时,效果很好。有什么解释吗?假设你得到了'10,20,30'
。你用它做什么g.group\u id IN(10,20,30)
(三个数字)或g.group\u id IN('10,20,30')
(一个字符串)?我注意到我重写了错误的查询。现在就去看看。我应该得到多个人ID,而不是团体ID。这并不重要;多个id是否作为字符串返回?是的,我会这样说,因为列person_id的类型是varchar2。能否显示所有三个表的表定义(特别是id列类型);以及如何定义:其他\u id
?您可能正在将一个数字列连接到一个您认为只有数字的varchar,或者只与数字匹配的varchar,并且它被一个您不希望相关的非数字值绊倒。我只是注意到我最初的查询是错误的。我更新了它。person\u id
在other
中是逗号分隔的列表吗?如果是这样,那在in
子句中是行不通的。您需要将字符串解析为一个集合,并在查询中使用该集合。但是,您不应该首先在关系数据库中存储以逗号分隔的键列表,因此您可能希望修复数据模型;以及如何定义:其他\u id
?你可能加入了一个c号码