2016-11-29 2 views
0

У меня есть запрос, как это:Подзапрос возвратил более 1 значения. В SQL Server

SELECT F_Asset_Code, F_Unit_Price, F_ServiceStart 
FROM T_Assets 
    where F_ServiceStart <= '2016-10-31' and F_ServiceStart<>'1900-01-01' 
    and F_Asset_CurrentValue <> '0.00' or F_Asset_CurrentValue is null 

если добавить условие, как это я получаю ошибку

SELECT F_Asset_Code, F_Unit_Price, (select F_SLM_Years from T_L1Category 
where F_L1Cat_Code=T_Assets.F_L1Cat_Code) as F_SLM_Years, F_ServiceStart 
FROM T_Assets 
    where F_ServiceStart <= '2016-10-31' and F_ServiceStart<>'1900-01-01' 
    and F_Asset_CurrentValue <> '0.00' or F_Asset_CurrentValue is null 

Ошибка:

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

+3

Сообщение об ошибке должно быть достаточно ясным, ваш подзапрос не может возвращать более одного значения. –

+0

Используйте верхнюю часть 1 во внутреннем выборе. Что вы пытаетесь достичь? Топ 1 может не соответствовать вашим потребностям. –

+0

Ошибка сама по себе F_SLM_Years из T_L1Категория, имеющая более одного значения для этого F_L1Cat_Code. – Mani

ответ

-1

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

Возьмите этот запрос и запустите его самостоятельно, и вы увидите это. Измените подзапрос, чтобы вернуть только одно соответствующее значение, и все будет в порядке.

+0

sir Мне нужно получить всю ценность там – user3262364

+1

@ user3262364 Вы не можете иметь более одной строки, возвращенной в подзапросе, когда используется в выражении 'select'. Это просто невозможно. Если вам нужно несколько строк строк данных, вам нужно использовать 'join'. – iamdave

1

Шаг 1: Выясните данные, которые вызвали проблемы в T_L1Category

SELECT * 
FROM T_L1Category 
WHERE F_L1Cat_Code IN (SELECT F_L1Cat_Code 
          FROM  (SELECT F_L1Cat_Code , 
               COUNT(1) 1 
             FROM  T_L1Category 
             GROUP BY F_L1Cat_Code 
             HAVING COUNT(1) > 1 
            ) tb1) 

Шаг 2: По результату шага 1, выяснить, почему, где более одной записи в T_L1Category с тем же F_L1Cat_Code

Шаг 3: по результату шага 2, вы можете использовать метод ниже, чтобы решить проблему

a) 
SELECT TOP 1 
     F_SLM_Years 
FROM T_L1Category 
WHERE F_L1Cat_Code = T_Assets.F_L1Cat_Code 
ORDER BY XXX 

b) 
SELECT F_SLM_Years 
FROM T_L1Category 
WHERE F_L1Cat_Code = T_Assets.F_L1Cat_Code 
     AND XXX = YYY 

c) 
SELECT DISTINCT 
     F_SLM_Years 
FROM T_L1Category 
WHERE F_L1Cat_Code = T_Assets.F_L1Cat_Code 
+0

Кроме того, я думаю, что использовать [F_Asset_CurrentValue> '0' или F_Asset_CurrentValue как '-'] вместо [F_Asset_CurrentValue <> '0,00'] может быть лучше –

+0

[F_Asset_CurrentValue> '0' или F_Asset_CurrentValue как '-%'], когда F_Asset_CurrentValue = «0,000» –

1

Использование левого соединения должно работать, я предполагаю, что вы ожидаете нулевые значения.

Это также предполагает, что вы хотите получить несколько значений, возвращаемых для F_SLM_Years; и, основываясь на комментариях, я считаю, что предположение верно.

Также обратите внимание: вы также должны использовать() вокруг OR и соответствующие, и в случае, если кто-то позже добавляет условие или повторно упорядочивает порядок места. Такие, как:

and (F_Asset_CurrentValue <> '0.00' or F_Asset_CurrentValue is null)

Однако я предпочитаю другой подход к или. A coalesce может полностью исключить ИЛИ. Также показалось странным сравнивать то, что я считаю, типом данных валюты (числовым) для строки, поэтому я исключил одинарные кавычки и .00.

SELECT F_Asset_Code, F_Unit_Price, F_SLM_Years, F_ServiceStart 
FROM T_Assets 
LEFT JOIN T_L1Category 
    ON T_L1Category.F_L1Cat_Code=T_Assets.F_L1Cat_Code 
WHERE F_ServiceStart <= '2016-10-31' 
    and F_ServiceStart<>'1900-01-01' 
    and coalesce(F_Asset_CurrentValue,0) <> 0 

Последн F_ServiceStart <> '1900-01-01' кажется странным. Является ли это жестко запрограммированным значением системы или действительно нулем, отображаемым как 1/1/1900? в этом случае вам нужно будет устранить Nulls?

and F_ServiceStart is not null вместо F_ServiceStart<>'1900-01-01'?

0

Если у вас возникла такая ошибка, вы должны сначала понять , почему вы получаете более одного значения и имеете ли деловые правила, что вам нужно показать все из них, или, если у вас должен быть только один, то что бизнес-правило, вам нужно использовать, чтобы ограничить его только одним. Это не то, что вы можете делать волей-неволей.Вам нужно понять данные, чтобы понять, что вы должны сделать, чтобы исправить это. Все следующие фрагменты кода, в зависимости от фактических данных, может устранить ошибку, только один может дать правильный ответ:

Комплектование наибольшее значение

SELECT F_Asset_Code, F_Unit_Price, (select top 1 F_SLM_Years from T_L1Category 
where F_L1Cat_Code=T_Assets.F_L1Cat_Code order by F_SLM_Years desc) as F_SLM_Years, F_ServiceStart 
FROM T_Assets 
    where F_ServiceStart <= '2016-10-31' and F_ServiceStart<>'1900-01-01' 
    and F_Asset_CurrentValue <> '0.00' or F_Asset_CurrentValue is null 

Комплектование наименьшее значение

SELECT F_Asset_Code, F_Unit_Price, (select MIN(F_SLM_Years) from T_L1Category 
where F_L1Cat_Code=T_Assets.F_L1Cat_Code) as F_SLM_Years, F_ServiceStart 
FROM T_Assets 
    where F_ServiceStart <= '2016-10-31' and F_ServiceStart<>'1900-01-01' 
    and F_Asset_CurrentValue <> '0.00' or F_Asset_CurrentValue is null 

Агрегирование значения

SELECT F_Asset_Code, F_Unit_Price, (select SUM(F_SLM_Years) from T_L1Category 
where F_L1Cat_Code=T_Assets.F_L1Cat_Code) as F_SLM_Years, F_ServiceStart 
FROM T_Assets 
    where F_ServiceStart <= '2016-10-31' and F_ServiceStart<>'1900-01-01' 
    and F_Asset_CurrentValue <> '0.00' or F_Asset_CurrentValue is null 

Сбор одну базовую величину d на дополнительные где условия (при условии, когда условие 100% времени будет возвращать только 1 значение!)

SELECT F_Asset_Code, F_Unit_Price, (select F_SLM_Years from T_L1Category 
where F_L1Cat_Code=T_Assets.F_L1Cat_Code and F_L1Cat_Code= 'test') as F_SLM_Years, F_ServiceStart 
FROM T_Assets 
    where F_ServiceStart <= '2016-10-31' and F_ServiceStart<>'1900-01-01' 
    and F_Asset_CurrentValue <> '0.00' or F_Asset_CurrentValue is null 

Использование присоединиться, чтобы вернуть все записи

SELECT F_Asset_Code, F_Unit_Price, F_SLM_Years, F_ServiceStart 
FROM T_Assets 
LEFT JOIN T_L1Category 
    ON T_L1Category.F_L1Cat_Code=T_Assets.F_L1Cat_Code 
WHERE F_ServiceStart <= '2016-10-31' 
    and F_ServiceStart<>'1900-01-01' 
    and (F_Asset_CurrentValue <> '0.00' or F_Asset_CurrentValue is null) 

Использование функции вещи в объединить несколько результатов для этого одного поля в строку

select F_Asset_Code, F_Unit_Price, STUFF((SELECT ' ' + cast(F_SLM_Years as nvarchar) 
     FROM T_L1Category 
     where F_L1Cat_Code=T_Assets.F_L1Cat_Code 
     FOR XML PATH('')), 1, 1, '' 
     ) 
FROM T_Assets 
    where F_ServiceStart <= '2016-10-31' and F_ServiceStart<>'1900-01-01' 
    and F_Asset_CurrentValue <> '0.00' or F_Asset_CurrentValue is null 
Смежные вопросы