Куда мне поместить инструкцию if?

#sql-server #if-statement #group-by

#sql-server #if-statement #группировать по

Вопрос:

Я написал это, чтобы создать сводку счетов за последние 30 дней. При проверке счетов-фактур я заметил, что извлек много нулей, потому что большинство клиентов не облагаются налогом. Я хотел бы поместить оператор IF (ЕСЛИ t.TAXABL_23 = ‘N’, то что-нибудь, чтобы сделать tax = 1 … здесь он становится немного серым) Куда в этом беспорядке могла бы пойти инструкция if, или, что еще лучше, логичным способом сделать это является использование инструкции IF. Спасибо.

 Select  c.ordnum_31 as "Sales Order Number",
    c.invce_31  as "Invoice Number",    
    c.custpo_31 as "Job Name",
    c.ordid_31  as "Other Job Name", 
    c.invdte_31 as "Invoice Date",
    cast (sum((1-(m.DSCRTE_23/100)) * (o.price_32 * o.shpqty_32)) as decimal    (8,2)) as "Net Amount",
    cast (c.frtamt_31 as decimal(8,2)) as Freight,
    cast( ((t.TAXRTE_25 * .01) * c.TAXTOT_31)  as decimal (8,2)) as Tax,
    cast (c.MSCAMT_31 as decimal(8,2)) as MISC,
    cast( round (sum((1-(m.DSCRTE_23/100)) * (o.price_32 * o.shpqty_32))   c.frtamt_31   c.MSCAMT_31   ((t.TAXRTE_25 * .01) * c.TAXTOT_31),1 ) as decimal(8,2) ) as "Invoice Total" 

from Invoice_Master c
   left join Invoice_Detail o on c.ORDNUM_31 = o.ORDNUM_32
   left join Customer_Master m on c.CUSTID_31 = m.CUSTID_23
   left join Tax_master t on m.TXCDE1_23 = t.TAXCDE_25

where c.invdte_31 >= DATEADD(day,-30, getdate())

group by
   c.ORDNUM_31,
   c.CUSTID_31,
   c.INVCE_31,
   c.CUSTPO_31,
   c.ORDID_31,
   c.INVDTE_31,
   c.frtamt_31,
   c.taxtot_31,
   m.dscrte_23,
   c.MSCAMT_31,
   t.taxrte_25

order by "Invoice Number"
  

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

1. Они на самом деле NULL или это 'N' они?

2. Можете ли вы включить некоторые примеры данных и ожидаемый результат?

3. @bjones, они равны нулю, если налогооблагаемый флаг равен N.

4. Возможно, немного больше деталей окажется полезным. Я не совсем уверен, о чем вы просите… Если бы я должен был догадаться об этом, я бы сказал добавить ISNULL() вокруг всего столбца. например ISNULL(cast( ((t.TAXRTE_25 * .01) * c.TAXTOT_31) as decimal (8,2)), 1) Tax,

5. Что я хотел бы сделать, так это если t.TAXABL_23 = ‘N’, то обойти часть вычисления налога. В противном случае выполните вычисление налога как обычно.

Ответ №1:

Вероятно, вы ищете выражение CASE:

 ...
... as Freight,
CASE WHEN t.TAXABL_23 = 'N'
     THEN 0                  -- exempt from taxes
     ELSE ...calculate tax...
END as Tax,
... as MISC,
...
  

В противном случае, если вы просто хотите преобразовать нули в некоторое значение, вы можете использовать выражение ISNULL:

 ...
ISNULL(...calculate tax..., 0) AS tax   -- yields 0 when the result of the expression is NULL
...
  

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

1. СЛУЧАЙ, КОГДА t.TAXABL_23 = ‘N’ затем преобразуется ( round (sum((1-(m.DSCRTE_23/ 100)) * (o.price_32 * o.shpqty_32)) c.frtamt_31 c.MSCAMT_31 ,1 ) в десятичное число (8,2) ) в качестве «Итога счета», ОСТАЛЬНОЕ преобразуется( ((t.TAXRTE_25 * .01) * c.TAXTOT_31) в десятичное число (8,2)) как налог, приведите ( round (sum((1-(m.DSCRTE_23 / 100)) * (o.price_32 * o.shpqty_32)) c.frtamt_31 c.MSCAMT_31 ((t.TAXRTE_25 * .01) * c.TAXTOT_31), 1 ) как десятичный (8,2) ) как «Общая сумма счета», конец из Invoice_Master c, но синтаксис отключен … не могли бы вы расширить свой ответ? Спасибо

2. ну, этот комментарий выглядит дерьмово, и я не могу найти, как его удалить … извините

3. @Onyxtacular: «КАК …» должно быть вне предложения case, т.е. после END .

4. Это сделало это идеально. Спасибо!

Ответ №2:

Используйте COALESCE для преобразования NULLS

  SELECT COALESCE(fieldWithNull, 'N');
  

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

1. Зачем использовать COALESCE , когда есть только одно значение?

2. OP say получает много null и вместо NULL want 'N' .

3. Да, но почему вы предпочли бы COALESCE over ISNULL в этом конкретном случае? ISNULL мне кажется, это логичный выбор.

4. @Jens, насколько я понимаю COALESCE , это стандарт ansi,

5. Ознакомьтесь с этой статьей о различиях. sqlmag.com/t-sql/coalesce-vs-isnull