сумма COALESCE 0 вместо нуля - PullRequest
2 голосов
/ 02 ноября 2011

я не могу добавить нулевые значения вместо нуля, вот мой sql:

 SELECT
                        S.STOCK_ID,
                        S.PRODUCT_NAME,
                        SUM(COALESCE(AMOUNT,0)) AMOUNT,
                        DATEPART(MM,INVOICE_DATE) AY
                    FROM
                        #DSN3_ALIAS#.STOCKS S
                            LEFT OUTER JOIN DAILY_PRODUCT_SALES DPS ON S.STOCK_ID = DPS.PRODUCT_ID
                    WHERE
                        MONTH(INVOICE_DATE) >= #attributes.startdate# AND 
                        MONTH(INVOICE_DATE) < #attributes.finishdate+1#
                    GROUP BY
                        DATEPART(MM,INVOICE_DATE),
                        S.STOCK_ID,
                        S.PRODUCT_NAME
                    ORDER BY
                        S.PRODUCT_NAME

и моя таблица:

<cfoutput query="get_sales_total" group="stock_id">
                            <tr height="20" class="color-row">
                                <td>#product_name#</td>
                                <cfoutput group="ay"><td><cfif len(amount)>#amount#<cfelse>0</cfif></td></cfoutput>
                            </tr>
                        </cfoutput>

результат, который я хочу: enter image description here

и результат, который я получаю: enter image description here

спасибо всем за помощь!

+ РЕДАКТИРОВАТЬ:

Я использовалметод перекрестного соединения, переписал sql:

SELECT
                        SUM(COALESCE(AMOUNT,0)) AMOUNT,S.STOCK_ID,S.PRODUCT_NAME,DPS.AY
                    FROM
                        #DSN3_ALIAS#.STOCKS S
                            CROSS JOIN (SELECT DISTINCT <cfif attributes.time_type eq 2>DATEPART(MM,INVOICE_DATE) AY<cfelse>DATEPART(DD,INVOICE_DATE) AY</cfif> 
                            FROM DAILY_PRODUCT_SALES) DPS
                            LEFT OUTER JOIN DAILY_PRODUCT_SALES DP ON S.STOCK_ID = DP.PRODUCT_ID AND 
                            <cfif attributes.time_type eq 2>DATEPART(MM,DP.INVOICE_DATE)<cfelse>DATEPART(DD,DP.INVOICE_DATE)</cfif> = DPS.AY
                    WHERE
                    <cfif attributes.time_type eq 2>
                        MONTH(INVOICE_DATE) >= #attributes.startdate# AND 
                        MONTH(INVOICE_DATE) < #attributes.finishdate+1#
                    <cfelse>
                        MONTH(INVOICE_DATE) = #attributes.startdate#
                    </cfif>
                    <cfif len(trim(attributes.product_cat)) and len(attributes.product_code)>
                        AND S.STOCK_CODE LIKE '#attributes.product_code#%'
                    </cfif>
                    GROUP BY DPS.AY,S.STOCK_ID,S.PRODUCT_NAME
                    ORDER BY DPS.AY,S.STOCK_ID,S.PRODUCT_NAME

и в результате: enter image description here

Ответы [ 3 ]

1 голос
/ 02 ноября 2011

Вы можете сделать это в базе данных, как предложил Лассе, или вы можете обернуть каждое выходное значение в функцию Val, например:

<cfoutput group="ay"><td>#Val(amount)#</td></cfoutput>

Функция Val преобразует любое нечисловое значение в 0.

1 голос
/ 02 ноября 2011

Можете ли вы использовать вместо ISNULL, то есть;

 SUM(ISNULL(AMOUNT,0)) AMOUNT,

РЕДАКТИРОВАТЬ: хорошо, учитывая, что проблема, кажется, пропускает значения, а не нули как таковые. попробуйте что-нибудь подобное.

Во-первых, создайте постоянную таблицу report_framework. Этот основан на месяцах и годах, но вы могли бы расширить его на дни, если хотите.

</p> <pre><code>create table reporting_framework ([month] smallint, [year] smallint); go declare @year smallint; declare @month smallint; set @year=2000; while @year<2500 begin set @month=1; while @month<13 begin insert into reporting_framework ([month], [year]) values (@month, @year); set @month=@month+1; end set @year=@year+1; end select * from reporting_framework;

(это дает вам 6000 строк, от 2000 до 2499 - подстраивайтесь по вкусу!)

Теперь мы составим таблицу деталей и таблицу заказов

create table parts
([part_num] integer, [description] varchar(100));
go

insert into parts (part_num, [description]) values (100, 'Widget');
insert into parts (part_num, [description]) values (101, 'Sprocket');
insert into parts (part_num, [description]) values (102, 'Gizmo');
insert into parts (part_num, [description]) values (103, 'Foobar');

create table orders
([id] integer, part_num integer, cost numeric(10,2), orderdate datetime);
go

insert into orders ([id], part_num, cost, orderdate) values
(1, 100, 49.99, '2011-10-30');
insert into orders ([id], part_num, cost, orderdate) values
(2, 101, 109.99, '2011-10-31');
insert into orders ([id], part_num, cost, orderdate) values
(3, 100, 47.99, '2011-10-31');
insert into orders ([id], part_num, cost, orderdate) values
(4, 102, 429.99, '2011-11-01');
insert into orders ([id], part_num, cost, orderdate) values
(5, 101, 111.17, '2011-11-01');
insert into orders ([id], part_num, cost, orderdate) values
(6, 101, 111.17, '2011-11-01');
insert into orders ([id], part_num, cost, orderdate) values
(7, 103, 21.00, '2011-09-15');

Теперь это таблица, на которой вы основываете свой запрос, например;

select rf.month, rf.year, p.description, sum(isnull(o.cost,0))
from reporting_framework rf cross join parts p
full outer join orders o 
on rf.year=year(o.orderdate) and rf.month=month(o.orderdate)
and p.part_num=o.part_num
where rf.year='2011'
group by p.description, rf.month, rf.year
order by rf.year, rf.month, p.description

Этот пример помогает? Вероятно, есть множество более эффективных способов сделать это (привет StackOverflow), но это может заставить вас задуматься о том, в чем ваша проблема. Не CROSS JOIN, чтобы получить все комбинации деталей / дат, а затем FULL OUTER JOIN, чтобы получить в него заказы. Предложение where просто контролирует ваш диапазон дат.

1 голос
/ 02 ноября 2011

Используйте CASE вместо

СУММА (СЛУЧАЙ, КОГДА А НУЛЯЕТ ТОГДА 0, ИЛИ КОНЕЦ)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...