„JEŻELI” w instrukcji „SELECT” - wybierz wartość wyjściową na podstawie wartości kolumny

685
SELECT id, amount FROM report

Muszę amountbyć amountjeśli report.type='P'i -amountjeśli report.type='N'. Jak dodać to do powyższego zapytania?

Michał
źródło

Odpowiedzi:

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

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

Ponadto można obsługiwać, gdy warunek jest pusty. W przypadku kwoty zerowej:

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

Część IFNULL(amount,0)oznacza, gdy kwota nie jest zerową wartością zwrotu, w przeciwnym razie zwraca 0 .

Felipe Buccioni
źródło
5
Zastanawiam się, czy jest jakaś korzyść z używania tego IFNULL zamiast WĘGLA tutaj?
Chris
4
Ze źródła mysql widzę 2 definicje koalesce, jedną z 2 argumentami, a drugą z listą argumentów, ale ifnull wywołuje koalesce z 2 parametramisql/item_cmpfunc.h 722: Item_func_ifnull(Item *a, Item *b) :Item_func_coalesce(a,b) {}
Felipe Buccioni
2
Odpowiedź jest nieprawidłowa, jeśli istnieją inne typy raportów niż „N” i „P”, patrz komentarz BadHorsie w lepszym rozwiązaniu „case case”.
Trygve,
3
@Trygve Pytanie dotyczy 2 warunków i szukasz IFstwierdzenia, co jest nie tak?
Felipe Buccioni
2
@ Felipe, odpowiedź niekoniecznie jest w 100% poprawna, mogą istnieć inne typy raportów niż N i P. W twoim przypadku może to prowadzić do błędu, wybierając opcję -amount, jeśli typ raportu (na przykład) to „E”. Pytanie nie wspomina jednak, czy istnieją inne typy raportów, więc usuwam moją opinię. W takich przypadkach lubię programować defensywnie, więc zwróć się do innych czytelników.
Trygve
255

Użyj caseoświadczenia:

select id,
    case report.type
        when 'P' then amount
        when 'N' then -amount
    end as amount
from
    `report`
mellamokb
źródło
5
@Evan: True. Używam ich dla jasności. I tak nie ma to wpływu na nic.
mellamokb
3
Wolę standardową składnię ANSI niż niestandardową dla konkretnej bazy danych.
Gordon Linoff
2
Jest to najlepsze rozwiązanie, ponieważ zaakceptowane rozwiązanie odpowiedzi niekoniecznie jest odpowiednie, jeśli istnieją inne wartości dla report.type lub jeśli nowy report.type zostanie wprowadzony w późniejszym terminie. To mówiąc if report.type = 'P' use amount, otherwise use -amount for anything else. nie uwzględni typu, jeśli nie jest to „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;
użytkownik1210826
źródło
43
select 
  id,
  case 
    when report_type = 'P' 
    then amount 
    when report_type = 'N' 
    then -amount 
    else null 
  end
from table
śpiewał kaul
źródło
15

Najprostszym sposobem jest użycie IF () . Tak MySQL pozwala na wykonywanie logiki warunkowej. JEŻELI funkcja przyjmuje 3 parametry WARUNEK, PRAWDA WYNIK, FAŁSZ WYNIK.

Więc logika jest

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

Możesz pominąć abs (), jeśli wszystkie nie są tylko + ve

aWebDeveloper
źródło
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
źródło
Ponieważ zestawy wyników wzajemnie się wykluczają, wolę tutaj UNION ALL.
Arth
4

Możesz także tego spróbować

 SELECT id , IF(type='p', IFNULL(amount,0), IFNULL(amount,0) * -1) as amount FROM table
Podstawowe zasady
źródło