Câu lệnh 'IF' trong 'CHỌN' - chọn giá trị đầu ra dựa trên các giá trị cột


685
SELECT id, amount FROM report

Tôi cần amountphải là amountnếu report.type='P'-amountnếu report.type='N'. Làm thế nào để tôi thêm điều này vào truy vấn trên?

Câu trả lời:


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

Xem http://dev.mysql.com/doc/refman/5.0/en/control-flow-fifts.html .

Ngoài ra, bạn có thể xử lý khi điều kiện là null. Trong trường hợp số tiền không có giá trị:

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

Phần IFNULL(amount,0)có nghĩa là khi số tiền không phải là số tiền trả về thì số tiền khác trả về 0 .


5
Tôi tự hỏi liệu có bất kỳ lợi thế nào khi sử dụng IFNULL này thay vì COALESCE ở đây không?
Chris

4
Từ nguồn mysql, tôi nhận thấy 2 định nghĩa về sự kết hợp, một định nghĩa có 2 đối số và một với một danh sách các đối số, nhưng ifnull gọi phép kết hợp với 2 tham sốsql/item_cmpfunc.h 722: Item_func_ifnull(Item *a, Item *b) :Item_func_coalesce(a,b) {}
Felipe Buccioni

2
Câu trả lời là không chính xác nếu có các loại báo cáo khác với 'N' và 'P', xem nhận xét của BadHors trong giải pháp "tuyên bố trường hợp" tốt hơn.
Thử

3
@Trygve Câu hỏi dành cho 2 điều kiện và tìm kiếm một IFtuyên bố, có gì sai?
Felipe Buccioni

2
@Felipe, câu trả lời không nhất thiết đúng 100%, có thể có các loại báo cáo khác ngoài N và P. Trong trường hợp của bạn, điều này có thể dẫn đến lỗi, chọn -amount nếu loại báo cáo (ví dụ) là 'E'. Câu hỏi không đề cập đến nếu có các loại báo cáo khác, vì vậy tôi loại bỏ downvote của tôi. Tôi chỉ thích lập trình phòng thủ trong những trường hợp này, vì vậy hãy hướng đến những độc giả khác.
Thử

255

Sử dụng một casetuyên bố:

select id,
    case report.type
        when 'P' then amount
        when 'N' then -amount
    end as amount
from
    `report`

5
@Evan: Đúng. Tôi sử dụng chúng cho rõ ràng. Không phải là nó ảnh hưởng đến bất cứ điều gì.
mellamokb

3
Tôi thích cú pháp tiêu chuẩn ANSI hơn cú pháp tùy chỉnh cho một cơ sở dữ liệu cụ thể.
Gordon Linoff

2
Đây là giải pháp tốt nhất vì giải pháp trả lời được chấp nhận không nhất thiết phù hợp nếu có các giá trị khác cho báo cáo.type hoặc nếu một báo cáo mới.type được giới thiệu vào một ngày sau đó. Nó đang nói if report.type = 'P' use amount, otherwise use -amount for anything else. nó sẽ không xem xét loại nếu nó không phải là '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;

43
select 
  id,
  case 
    when report_type = 'P' 
    then amount 
    when report_type = 'N' 
    then -amount 
    else null 
  end
from table

15

Cách đơn giản nhất là sử dụng IF () . Có Mysql cho phép bạn làm logic có điều kiện. Hàm IF có 3 tham số ĐIỀU KIỆN, TRUE OUTCOME, FALSE OUTCOME.

Vậy logic là

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

Bạn có thể bỏ qua abs () nếu tất cả không chỉ là + ve


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

UNION

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

ORDER BY id;

Vì các tập kết quả là loại trừ lẫn nhau, tôi thích UNION ALL ở đây.
Arth

4

Bạn cũng có thể thử điều này

 SELECT id , IF(type='p', IFNULL(amount,0), IFNULL(amount,0) * -1) as amount FROM table
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.