Как использовать подзапрос для создания нового столбца

#sql #sql-server #xml #subquery

Вопрос:

У меня возникли некоторые проблемы с запросом для получения некоторой информации

 select id_column, d_description
from table1
where (select substring(cast(g_xml_comprobante as nvarchar(max)), charindex('contrato=', cast(g_xml_comprobante as nvarchar(max)))   10, 15) as 'contract' 
       from table1 a, table 3 b
       where convert(varchar(6), b.d_date, 112) > '202108' 
         and b.id_column = a.id_column) = '2019896177'
 

Я получаю эту ошибку:

Msg 512, Уровень 16, Состояние 1,
Подзапрос строки 1 вернул более 1 значения. Это недопустимо, если подзапрос следует =, !=, <, <= , >, <= , >>= или когда подзапрос используется в качестве выражения.

Ситуация выглядит так: у нас есть XML — информация в столбце внутри таблицы1, в XML у нас есть номер контракта. Итак, я хочу получить все идентификаторы из определенных контрактов, у меня есть значения контрактов, поэтому мне нужно, чтобы это было где.

Возможно ли это осуществить?

Если мне не ясно, пожалуйста, дайте мне знать, чтобы я мог уточнить.

Спасибо за помощь!

Комментарии:

1. Вредные привычки : использование соединений в старом стиле -этот стиль списка таблиц, разделенных запятыми в старом стиле, был заменен правильным JOIN синтаксисом ANSI в стандарте SQL ANSI — 92 ( почти 30 лет назад), и его использование не рекомендуется

Ответ №1:

То, что написал Серж, тоже верно. Но если вы просто проверяете, что конкретный идентификатор контракта существует в вашем подзапросе, и по какой-то причине несколько строк имеют один и тот же контракт, то вы можете сделать следующее. Вы можете использовать в предложении, как показано ниже

 select id_column, d_description
from table1
where '2019896177' in (select substring(CAST(g_xml_comprobante as nvarchar(max)),CHARINDEX('contrato=',CAST(g_xml_comprobante as nvarchar(max))) 10,15) as 'contract' from table1 a,table3 b
where convert(varchar(6),b.d_date,112) > '202108' and b.id_column=a.id_column
)
 

однако второй подход, который довольно распространен при работе с ошибками такого типа, но в основном зависит от ваших данных, какие данные возвращаются.
если ваш подзапрос возвращает одинаковое значение для всех строк, то лучше всего использовать Top 1 его в вашем подзапросе.

 select id_column, d_description
from table1
where (select Top 1 substring(CAST(g_xml_comprobante as nvarchar(max)),CHARINDEX('contrato=',CAST(g_xml_comprobante as nvarchar(max))) 10,15) as 'contract' from table1 a,table3 b
where convert(varchar(6),b.d_date,112) > '202108' and b.id_column=a.id_column
)='2019896177'
 

Ответ №2:

В вашем запросе есть ряд проблем:

 select
  t1.id_column,
  t1.d_description
from table1 t1
where exist (select 1
    from [table 3] t3
    where t3.d_date > '202108'
      and t3.id_column = t1.id_column
       -- not sure exactly what XQuery you are looking for
      and t3.g_xml_comprobante.exist('//@contrato[. = "2019896177"]') = 1
);
 

Ответ №3:

Вы пытаетесь сравнить результаты подзапроса с константой. Но ваш подзапрос возвращает более одного значения. В таком случае вы можете использовать ЛЮБОЙ или ВСЕ до подзапроса. ЛЮБОЕ означает, что результат является истинным, если какое-либо из возвращаемых значений соответствует условию. ВСЕ это означает, что результат является истинным, если все возвращаемые значения соответствуют условию.