'IF' na instrução 'SELECT' - escolha o valor de saída com base nos valores da coluna

685
SELECT id, amount FROM report

Eu preciso amountser amountse report.type='P'e -amountse report.type='N'. Como adiciono isso à consulta acima?

Michael
fonte

Respostas:

1025
SELECT id, 
       IF(type = 'P', amount, amount * -1) as amount
FROM report

Consulte http://dev.mysql.com/doc/refman/5.0/en/control-flow-functions.html .

Além disso, você pode manipular quando a condição é nula. No caso de um valor nulo:

SELECT id, 
       IF(type = 'P', IFNULL(amount,0), IFNULL(amount,0) * -1) as amount
FROM report

A parte IFNULL(amount,0)significa que quando o valor não for nulo, o valor retornado será o retorno 0 .

Felipe Buccioni
fonte
5
Gostaria de saber se existe alguma vantagem em usar esse IFNULL em vez de COALESCE aqui?
31413 Chris
4
De fonte mysql, noto 2 definições de coalesce, um com 2 argumentos, e outro com uma lista de argumentos, mas IFNULL invoca o coalesce com 2 parâmetrossql/item_cmpfunc.h 722: Item_func_ifnull(Item *a, Item *b) :Item_func_coalesce(a,b) {}
Felipe Buccioni
2
A resposta não está correta se houver tipos de relatório diferentes de 'N' e 'P'; consulte o comentário de BadHorsie na melhor solução de "declaração de caso".
Trygve
3
@Trygve A pergunta é para duas condições e, procurando uma IFdeclaração, o que há de errado?
Felipe Buccioni 31/01
2
@Felipe, a resposta não é necessariamente 100% correta, pode haver outros tipos de relatório além de N e P. No seu caso, isso pode levar a um erro, selecionando -mount se o tipo de relatório (como exemplo) for 'E'. A pergunta não menciona se existem outros tipos de relatório, então removo meu voto negativo. Eu só gosto de programar defensivamente nesses casos, então lembre-se de outros leitores.
Trygve 27/02
255

Use uma casedeclaração:

select id,
    case report.type
        when 'P' then amount
        when 'N' then -amount
    end as amount
from
    `report`
mellamokb
fonte
5
@Evan: Verdade. Eu os uso para maior clareza. Não que isso afete algo de qualquer maneira.
Mellamokb
3
Eu prefiro a sintaxe padrão ANSI do que a sintaxe personalizada para um banco de dados específico.
Gordon Linoff
2
Essa é a melhor solução, porque a solução de resposta aceita não é necessariamente apropriada se houver outros valores para report.type ou se um novo report.type for introduzido posteriormente. Está dizendo if report.type = 'P' use amount, otherwise use -amount for anything else. não considerará o tipo se não for 'P'.
precisa saber é o seguinte
97
SELECT CompanyName, 
    CASE WHEN Country IN ('USA', 'Canada') THEN 'North America'
         WHEN Country = 'Brazil' THEN 'South America'
         ELSE 'Europe' END AS Continent
FROM Suppliers
ORDER BY CompanyName;
user1210826
fonte
43
select 
  id,
  case 
    when report_type = 'P' 
    then amount 
    when report_type = 'N' 
    then -amount 
    else null 
  end
from table
cantou kaul
fonte
15

A maneira mais simples é usar um IF () . Sim O Mysql permite fazer lógica condicional. A função SE leva três parâmetros: CONDIÇÃO, RESULTADO VERDADEIRO, RESULTADO FALSO.

Então a lógica é

if report.type = 'p' 
    amount = amount 
else 
    amount = -1*amount 

SQL

SELECT 
    id, IF(report.type = 'P', abs(amount), -1*abs(amount)) as amount
FROM  report

Você pode pular abs () se todos os nãos forem apenas + ve

aWebDeveloper
fonte
12
SELECT id, amount
FROM report
WHERE type='P'

UNION

SELECT id, (amount * -1) AS amount
FROM report
WHERE type = 'N'

ORDER BY id;
linitux
fonte
Como os conjuntos de resultados são mutuamente exclusivos, prefiro UNION ALL aqui.
Arth
4

Você pode tentar isso também

 SELECT id , IF(type='p', IFNULL(amount,0), IFNULL(amount,0) * -1) as amount FROM table
Regras Basantes
fonte