2015-01-20 7 views
0

У меня есть список параметров, которые являются первым диапазоном дат @start_dt и @end_dt одним из моих полей является режим. если mode = 1, запрос запускается в одну сторону, если режим - 2, другой и т. д. У меня есть 7 возможных версий.Группировка ошибок по сумме одного столбца к общему значению другого

, когда режим = 6, я хочу сказать, что вытащить все столбцы между диапазоном диапазона дат ниже и где один столбец pmt_rcvd_amt не равен сумме sli_paid_amt. Теперь я хочу sli_paid_amt сгруппированных по customer_no

Where a.create_dt between @start_dt and @end_dt and a.pmt_rcvd_amt <> sum(a.sli_paid_amt)

Например:

customer_no sli_due_amt pmt_rcvd_amt` 
85244305 200.00 200.00 
74500386 50.00 219.00 
74500386 219.00 219.00 
74500386 10.00 219.00 
86119821 NULL NULL 

Я хочу, чтобы взять на customer_no 74500386
это сгруппировать их (суммировать все sli_due_amt) так 219 + 50. + 10, таким образом, 279, а затем сравните его с столбцом 219 в pmt_rcvd_amt. (Эти значения будут одинаковы)

мой код выглядит следующим образом ...

select distinct 
     a.id_key , 
     a.customer_no , 
     a.customer_prefix , 
     a.customer_lname 
     ... 
     a.current_child_price , 
     a.current_other_price 
     from LV_CHC_TOURS_RSV_DATA a 
     left outer join LT_CHC_TOURS_RSV_LANG b on a.language = b.id 
     left outer join LV_CHC_TOURS_RSV_CS c on a.add_text = c.source_no 
     Where a.create_dt between @start_dt and @end_dt 
     and a.pmt_rcvd_amt <> sum(a.sli_paid_amt) 

Error Message: An aggregate may not appear in the WHERE clause unless it is in a subquery contained in a HAVING clause or a select list, and the column being aggregated is an outer reference. 

Затем я изменил его, чтобы попытаться использовать, имея в своем коде:

from LV_CHC_TOURS_RSV_DATA a 
     left outer join LT_CHC_TOURS_RSV_LANG b on a.language = b.id 
     left outer join LV_CHC_TOURS_RSV_CS c on a.add_text = c.source_no 
     Where a.create_dt between @start_dt and @end_dt 
     group by a.customer_no 
     having sum(a.sli_paid_amt) <> a.pmt_rcvd_amt 

и Теперь я получаю следующее сообщение об ошибке:

Column 'LV_CHC_TOURS_RSV_DATA.pmt_rcvd_amt' is invalid in the HAVING clause because it is not contained in either an aggregate function or the GROUP BY clause. 

Я знаю его немного странным - но я хочу для данного customer_no просуммировать все т он sli_due_amts, а затем посмотреть, равны ли они равному значению pmt_rcvd_amt. потому что эти разные значения будут одинаковыми в каждой строке.

, что мой желаемый результат:

customer_no sli_due_amt pmt_rcvd_amt` 
74500386 50.00 219.00 
74500386 219.00 219.00 
74500386 10.00 219.00 

потому что: 50 + 219 + 10 не равна 219 (сгруппированных клиентом 74500386)

+0

Можете ли вы дать нам ожидаемый результат, используя образец, который вы нам дали? Также обратите внимание, что «эти разные значения будут одинаковыми в каждой строке», это нехорошо иметь в базе данных. Представьте, что вы хотите изменить pmt_rcvd_amt в одной записи, вам нужно будет изменить его во всех остальных. –

+0

Если вы знаете, что значение a.pmt_rcvd_amt всегда будет одинаковым для каждой строки, вы можете использовать произвольную агрегированную функцию, например min или max, для возврата «некоторого» значения. «Правильный» способ сделать это - создать таблицу вывода, содержащую агрегированные данные, и другую таблицу вывода, содержащую значение singleton, с которым вы его сравниваете. Хотя есть много раз, это просто не под вашим контролем, я согласен с @LuisAlves, что это похоже на плохой дизайн базы данных. – Xedni

+0

Используйте подзапрос в своем предложении WHERE. Так что a.pmt_rcvd_amt <> (некоторый запрос, который извлекает SUM для клиента) –

ответ

1
SELECT a.customer_no, SUM(a.sli_paid_amt), MAX(a.pmt_rcvd_amt) AS [Payment Amount], MAX(some_other_field), ... 
from LV_CHC_TOURS_RSV_DATA a 
     left outer join LT_CHC_TOURS_RSV_LANG b on a.language = b.id 
     left outer join LV_CHC_TOURS_RSV_CS c on a.add_text = c.source_no 
     Where a.create_dt between @start_dt and @end_dt 
     group by a.customer_no 
     having sum(a.sli_paid_amt) <> [Payment Amount] 

Если поле не в группе, то она должна быть агрегатной функции, такие как SUM/MAX и т.д ... Если группа по идентификатору клиента выше запрос должен работать. Затем просто поместите поля в ваш оператор select с помощью MAX (-), потому что MAX также можно использовать с полями символов.

+0

Проблема в том, что я хочу, чтобы запрос возвращал поля индивидуально, другими словами мне нужны три строки, возвращенные для customer_no 74500386 и Мне нужны уникальные элементы - 10, 219 и 50 отдельных, поэтому я не могу их максимизировать в инструкции select. другими словами, мне нужен запрос, чтобы возвращать все уникальные строки, где сумма одного поля не вычисляет значение в другом, но мне все еще нужно видеть все части полей. – YelizavetaYR

+0

Можете ли вы также группировать поля? –

+0

Нет, к сожалению, я просто хочу проверить, эквивалентна ли их сумма (сгруппирована по customer_no) и возвращать эти отдельные строки, если это не так. – YelizavetaYR

0

В HAVING пункте вы можете иметь только агрегатные функции. a.pmt_rcvd_amt то же самое для каждой строки, поэтому вы можете использовать min(a.pmt_rcvd_amt) или max(a.pmt_rcvd_amt)
В подзапросе ниже кода возвращаются номера всех клиентов, которые удовлетворяют вашим требованиям. Затем они используются основным запросом для выбора всех необходимых строк.

так попробовать это:

select 
    a.id_key , 
    a.customer_no , 
    a.customer_prefix , 
    a.customer_lname 
    ... 
    a.current_child_price , 
    a.current_other_price 
from LV_CHC_TOURS_RSV_DATA a 
    left outer join LT_CHC_TOURS_RSV_LANG b on a.language = b.id 
    left outer join LV_CHC_TOURS_RSV_CS c on a.add_text = c.source_no 
where a.customer_no in 
(select a1.customer_no from LV_CHC_TOURS_RSV_DATA a1  
    Where a1.create_dt between @start_dt and @end_dt 
    group by a1.customer_no 
    having sum(a1.sli_paid_amt) <> min(a1.pmt_rcvd_amt)) 
+0

Когда я попробую эту опцию, я получаю следующую ошибку: столбец «LV_CHC_TOURS_RSV_DATA.id_key» недопустим в списке выбора, потому что он не содержится ни в агрегатной функции, ни в предложении GROUP BY. Id_key - это еще один столбец в моем запросе. – YelizavetaYR

+0

так что вы говорите, я тяну запрос, как есть - где customer_no и фильтровать диапазон дат/и агрегаты во внутреннем выборе? – YelizavetaYR

+0

Внутренний запрос возвращает только разные 'customer_no', которые удовлетворяют требованиям. Они используются по основному запросу – rtruszk

0

Если вы правильно поняли, сначала вам нужно подвести итог sli_due_amt для каждого клиента, а затем вы хотите вернуть отдельные строки, за исключением клиентов, у которых есть pmt_rcvd_amt = суммарный sli_due_amt.

Итак:

WITH Summed as 
(select 
customer_no, 
sum(sli_due_amt) as sli_sum 
from LV_CHC_TOURS_RSV_DATA... 
GROUP BY cust_no 
) 

    select * 
    from 
    LV_CHC_TOURS_RSV_DATA t1 
    inner join summed 
     on t1.customer_no = summed.customer_no 
     and t1.pmt_rcvd_amt <> sli_sum 

Я сильно упрощённым ваш запрос, конечно.

+0

Мне не нужно суммировать их для вывода - мне нужно суммировать их для сравнения - где сумма sli_due_amt не равна pmt_rcvd_amt - но я хочу, чтобы выходной набор был уникальным отдельным столбцом. – YelizavetaYR

Смежные вопросы