Làm cách nào để nhân hàng cho một cột chứa giá trị âm và không?


10

Tôi đang cố gắng lấy Sản phẩm của tất cả các hàng cho một cột cụ thể trong một nhóm theo truy vấn. Hầu hết các ví dụ tôi đã tìm thấy tôi hướng tới việc kết hợp exp, sumlog

exp(sum(log([Column A])))

Vấn đề tôi gặp phải là cột chứa một số số không cho các giá trị và do đó tôi gặp lỗi này khi các số không được chuyển đến loghàm:

Một hoạt động điểm nổi không hợp lệ đã xảy ra.

Tôi nghĩ rằng tôi có thể giải quyết vấn đề này bằng cách sử dụng một casebiểu thức, nhưng điều đó không hoạt động theo cách tôi nghĩ nó nên, vì nó dường như đánh giá tất cả các trường hợp ...

select 
  Name,
  Product = case 
    when min([Value]) = 0 then 0 
    when min([Value]) <> 0 then exp(sum(log(I))) -- trying to get the product of all rows in this column
  end
 from ids
 group by Name

SqlFiddle

Cho tập kết quả sau:

Id  Name  Value
_________________________________
1   a     1
2   a     2
3   b     0
4   b     1

Tôi mong đợi để có được các hàng sau:

Name  Product
_____________
a     2
b     0

Vì vậy, tóm lại ... Làm thế nào để bạn nhân các hàng trong một cột có thể chứa các số có giá trị âm hoặc bằng 0?

Câu trả lời:


13

Sự kỳ diệu của NULLIF dường như thực hiện thủ thuật cho trường hợp thử nghiệm trong câu hỏi của bạn. Vì bạn đã sử dụng một ví dụ khác với trong Fiddle SQL của mình, tôi không biết đó có phải là điều bạn muốn ở đó không.

CREATE TABLE dbo.Ids
(
    Id INT NOT NULL IDENTITY(1, 1),
    Value INT,
    Name NVARCHAR(3)
);
INSERT INTO dbo.Ids ( Name, Value )
VALUES ( 'a', 1 );
INSERT INTO dbo.Ids ( Name, Value )
VALUES ( 'a', 2 );
INSERT INTO dbo.Ids ( Name, Value )
VALUES ( 'b', 0 );
INSERT INTO dbo.Ids ( Name, Value )
VALUES ( 'b', 1 );

SELECT   Name,
         CASE WHEN MIN(Value) = 0 THEN 0
              WHEN MIN(Value) > 0 THEN EXP(SUM(LOG(NULLIF(Value, 0)))) -- trying to get the product of all rows in this column
         END AS Product
FROM     Ids
GROUP BY Name;

Trả về:

Name    Product
a       2
b       0

Nếu bạn cần một giải pháp tổng quát hơn để xử lý các số âm và các trường hợp cạnh khác, hãy xem ví dụ Tổng hợp sản phẩm trong T-SQL so với CLR của Scott Burkow. Một cấu trúc T-SQL từ bài viết đó là:

EXP(SUM(LOG(NULLIF(ABS([Value]), 0))))
*
IIF(SUM(IIF([Value] = 0, 1, NULL)) > 0, 0, 1)
*
IIF(SUM(IIF([Value] < 0, 1, 0)) % 2 = 1, -1, 1)

Về lý do tại sao CASEbiểu thức ban đầu của bạn không hoạt động như mong đợi, từ tài liệu về CASE (Transact-SQL) (nhấn mạnh thêm):

Bạn chỉ nên phụ thuộc vào thứ tự đánh giá các điều kiện WHEN cho các biểu thức vô hướng (bao gồm các truy vấn phụ không tương quan trả về vô hướng), không phải cho các biểu thức tổng hợp .

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.