Можно ли получить несколько значений из подзапроса?
Есть ли способ, чтобы подзапрос возвращал несколько столбцов в oracle db? (Я знаю, что этот конкретный sql приведет к ошибке, но он подводит итог тому, что я хочу очень хорошо)
select
a.x,
( select b.y, b.z from b where b.v = a.v),
from a
Я хочу получить такой результат:
a.x | b.y | b.z
---------------
1 | 2 | 3
Я знаю, что можно решить эту проблему через объединения, но это не то, о чем я прошу.
Мой вопрос просто, если есть какой-либо способ, чтобы получить два или более значений из подзапроса? Может быть, обходной путь с использованием двойного? Так что нет никакого фактического соединения, но новый подзапрос для каждой строки?
РЕДАКТИРОВАТЬ: Это принципиальный вопрос. Я знаю, вы можете решить все эти проблемы, используя соединение. Вам вообще не нужны подзапросы (даже для одного столбца). Но они есть. Могу ли я использовать их таким образом или это просто невозможно?
Ответы
Ответ 1
Подзапрос в предложении Select, как и в вашем случае, также известен как Scalar Subquery, что означает, что это форма выражения. Это означает, что он может вернуть только одно значение.
Я боюсь, вы не сможете вернуть несколько столбцов из одного Скалярного подзапроса, нет.
Подробнее о Oracle Scalar Subqueries:
http://docs.oracle.com/cd/B19306_01/server.102/b14200/expressions010.htm#i1033549
Ответ 2
Это неверно, но вы можете попробовать это вместо этого:
select
a.x,
( select b.y from b where b.v = a.v) as by,
( select b.z from b where b.v = a.v) as bz
from a
Вы также можете использовать подзапрос в соединении
select
a.x,
b.y,
b.z
from a
left join (select y,z from b where ... ) b on b.v = a.v
или же
select
a.x,
b.y,
b.z
from a
left join b on b.v = a.v
Ответ 3
Вот два метода, чтобы получить более одного столбца в скалярном подзапросе (или встроенном подзапросе) и запросить таблицу поиска только один раз. Это немного запутанно, но может быть очень эффективным в некоторых особых случаях.
-
Вы можете использовать конкатенацию, чтобы получить несколько столбцов одновременно:
SELECT x,
regexp_substr(yz, '[^^]+', 1, 1) y,
regexp_substr(yz, '[^^]+', 1, 2) z
FROM (SELECT a.x,
(SELECT b.y || '^' || b.z yz
FROM b
WHERE b.v = a.v)
yz
FROM a)
Вам нужно убедиться, что ни один столбец в списке не содержит символ разделителя.
-
Вы также можете использовать объекты SQL:
CREATE OR REPLACE TYPE b_obj AS OBJECT (y number, z number);
SELECT x,
v.yz.y y,
v.yz.z z
FROM (SELECT a.x,
(SELECT b_obj(y, z) yz
FROM b
WHERE b.v = a.v)
yz
FROM a) v
Ответ 4
Вы не можете использовать JOIN, как этот?
SELECT
a.x , b.y, b.z
FROM a
LEFT OUTER JOIN b ON b.v = a.v
(я не знаю синтаксиса Oracle. Поэтому я написал синтаксис SQL)
Ответ 5
В запросе Oracle
select a.x
,(select b.y || ',' || b.z
from b
where b.v = a.v
and rownum = 1) as multple_columns
from a
можно преобразовать в:
select a.x, b1.y, b1.z
from a, b b1
where b1.rowid = (
select b.rowid
from b
where b.v = a.v
and rownum = 1
)
Полезно, когда мы хотим предотвратить дублирование для таблицы A.
Аналогично, мы можем увеличить количество таблиц:
.... where (b1.rowid,c1.rowid) = (select b.rowid,c.rowid ....
Ответ 6
вы можете использовать cross apply
:
select
a.x,
bb.y,
bb.z
from
a
cross apply
( select b.y, b.z
from b
where b.v = a.v
) bb
Если строка b не будет содержать строку a, тогда cross apply
не будет возвращать строку. Если вам нужны такие строки, используйте outer apply
Если вам нужно найти только одну конкретную строку для каждой строки из a, попробуйте:
cross apply
( select top 1 b.y, b.z
from b
where b.v = a.v
order by b.order
) bb
Ответ 7
Просмотреть этот веб-сайт: http://www.w3resource.com/sql/subqueries/multiplee-row-column-subqueries.php
Пример использования
select ord_num, agent_code, ord_date, ord_amount
from orders
where(agent_code, ord_amount) IN
(SELECT agent_code, MIN(ord_amount)
FROM orders
GROUP BY agent_code);