'IF' en la instrucción 'SELECT': elija el valor de salida en función de los valores de columna

685
SELECT id, amount FROM report

Necesito amountser amountsi report.type='P'y -amountsi report.type='N'. ¿Cómo agrego esto a la consulta anterior?

Miguel
fuente

Respuestas:

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

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

Además, puede manejar cuando la condición es nula. En el caso de una cantidad nula:

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

La parte IFNULL(amount,0)significa que cuando la cantidad no es nula, la cantidad devuelta, de lo contrario, devuelve 0 .

Felipe Buccioni
fuente
55
Me pregunto si hay alguna ventaja de usar este IFNULL en lugar de COALESCE aquí.
Chris
44
De la fuente mysql, noto 2 definiciones de fusión, una con 2 argumentos y otra con una lista de argumentos, pero ifnull invoca la fusión con 2 parámetrossql/item_cmpfunc.h 722: Item_func_ifnull(Item *a, Item *b) :Item_func_coalesce(a,b) {}
Felipe Buccioni
2
La respuesta no es correcta si hay diferentes tipos de informes que 'N' y 'P', vea el comentario de BadHorsie en la mejor solución de "declaración de caso".
Trygve
3
@ Trygve La pregunta es para 2 condiciones, y en busca de una IFdeclaración, ¿qué pasa?
Felipe Buccioni
2
@Felipe, la respuesta no es necesariamente 100% correcta, podría haber otros tipos de informes además de N y P. En su caso, esto podría conducir a un error, seleccionando -amount si el tipo de informe (como ejemplo) es 'E'. Sin embargo, la pregunta no menciona si hay otros tipos de informes, por lo que elimino mi voto negativo. Simplemente me gusta programar a la defensiva en estos casos, así que me dirijo a otros lectores.
Trygve
255

Use una casedeclaración:

select id,
    case report.type
        when 'P' then amount
        when 'N' then -amount
    end as amount
from
    `report`
mellamokb
fuente
55
@Evan: Cierto. Los uso para mayor claridad. No es que afecte nada de todos modos.
mellamokb
3
Prefiero la sintaxis estándar ANSI sobre la sintaxis personalizada para una base de datos particular.
Gordon Linoff
2
Esta es la mejor solución porque la solución de respuesta aceptada no es necesariamente apropiada si hay otros valores para report.type, o si se introduce un nuevo report.type en una fecha posterior. Que está diciendo if report.type = 'P' use amount, otherwise use -amount for anything else. no considerará el tipo si no es 'P'.
BadHorsie
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;
usuario1210826
fuente
43
select 
  id,
  case 
    when report_type = 'P' 
    then amount 
    when report_type = 'N' 
    then -amount 
    else null 
  end
from table
sang kaul
fuente
15

La forma más simple es usar un IF () . Sí Mysql te permite hacer lógica condicional. La función IF toma 3 parámetros CONDICIÓN, VERDADERO RESULTADO, FALSO RESULTADO.

Entonces la lógica es

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

Puede omitir abs () si todos los no son solo + ve

aWebDeveloper
fuente
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
fuente
Como los conjuntos de resultados son mutuamente exclusivos, prefiero UNION ALL aquí.
Arth
4

Puedes probar esto también

 SELECT id , IF(type='p', IFNULL(amount,0), IFNULL(amount,0) * -1) as amount FROM table
Reglas Basant
fuente