Áp dụng hàm tổng hợp MIN cho trường BIT


82

Tôi muốn viết truy vấn sau:

SELECT   ..., MIN(SomeBitField), ...
FROM     ...
WHERE    ...
GROUP BY ...

Vấn đề là, SQL Server không thích nó, khi tôi muốn tính giá trị nhỏ nhất của một trường bit, nó trả về lỗi Operand data type bit is invalid for min operator.

Tôi có thể sử dụng cách giải quyết sau:

SELECT   ..., CAST(MIN(CAST(SomeBitField AS INT)) AS BIT), ...
FROM     ...
WHERE    ...
GROUP BY ...

Nhưng, có cái gì thanh lịch hơn không? (Ví dụ: có thể có một hàm tổng hợp mà tôi không biết và nó đánh giá tính logic andcủa các giá trị bit trong một trường.)


2
@Adam Robinson: Rõ ràng,Operand data type bit is invalid for min operator.
Andomar

4
Không biết về thanh lịch hơn nhưng nó là một chút ngắn hơn. cast(min(SomeBitField+0) as bit)
Mikael Eriksson

5
@Andomar: Rõ ràng là nếu bạn đã biết vấn đề thì có, nhưng những người khác có vấn đề tương tự có thể tìm kiếm thông báo lỗi , vì vậy thông tin như vậy cần phải có trong câu hỏi.
Adam Robinson

Câu trả lời:


33

Vì chỉ có hai tùy chọn cho BIT, chỉ cần sử dụng một câu lệnh trường hợp:

SELECT CASE WHEN EXISTS (SELECT 1 FROM ....) THEN 1 ELSE 0 END AS 'MinBit'
FROM ...
WHERE ...

Điều này có lợi thế là:

  • Không buộc phải quét bảng (chỉ mục trên BITcác trường hầu như không bao giờ được sử dụng)
  • Điểm ngắn gọn về TWICE (một lần EXISTSvà một lần nữa cho CASE)

Nó là một đoạn mã nhiều hơn một chút để viết nhưng nó không phải là khủng khiếp. Nếu bạn có nhiều giá trị cần kiểm tra, bạn luôn có thể đóng gói tập hợp kết quả lớn hơn của mình (với tất cả JOINFILTERtiêu chí) trong CTEphần đầu của truy vấn, sau đó tham chiếu đến bộ CASEkết quả đó trong các câu lệnh.


10
Có ba tùy chọn bitnếu nó là nullable.
Martin Smith

1
Nếu bitcột bao gồm hoàn toàn các NULLgiá trị thì MINsẽ trả về NULL.
Martin Smith

8
Tôi phải là một lập trình viên "thấp hơn", nhưng tôi muốn xem một ví dụ đầy đủ về select 1 from ...truy vấn con. Nó không hoàn toàn có ý nghĩa.
Vaccano

2
@Vaccano -SELECT 1 FROM Outertable WHERE bitfield=1
JNK

2
Câu hỏi ban đầu bao gồm một GROUP BY. Bạn cần bao gồm nhóm theo tiêu chí trong WHERE.
Tmdean

156

Một lựa chọn là MIN(SomeBitField+0). Nó đọc tốt, với ít tiếng ồn hơn (mà tôi sẽ đủ tiêu chuẩn là sang trọng).

Điều đó nói rằng, đó là hack-ish hơn là CASEtùy chọn. Và tôi không biết gì về tốc độ / hiệu quả.


@Ben, Cảm ơn rất nhiều, Alson này giúp tôi về Truy vấn SQL của tôi.
PatsonLeaner

@Ben, bạn có một số tài liệu về +0 không ?, đã cố gắng tìm kiếm nó nhưng không tìm thấy gì cả, chỉ để tham khảo :)
Francisco Sevilla

1
@FranciscoSevilla Tôi tin rằng đó là do chuyển đổi ưu tiên ngầm: docs.microsoft.com/en-us/sql/t-sql/data-types/…
Ben Mosher

7

Truy vấn này là giải pháp tốt nhất:

SELECT CASE WHEN MIN(BitField+0) = 1 THEN 'True' ELSE 'False' END AS MyColumn
 FROM MyTable

Khi bạn thêm BitField + 0, nó sẽ tự động giống như int


7
select min(convert(int, somebitfield))

hoặc nếu bạn muốn giữ kết quả dưới dạng bit

select convert(bit, min(convert(int, somebitfield)))

6

Hãy thử lưu ý sau : Hàm đại diện tối thiểu và hàm tổng hợp, đại diện tối đa hoặc hàm tổng hợp

SELECT   ..., MIN(case when SomeBitField=1 then 1 else 0 end), MIN(SomeBitField+0)...
FROM     ...
WHERE    ...
GROUP BY ...

cùng một kết quả


5

Đoạn mã nhỏ này luôn hoạt động với tôi như một cái duyên:

CONVERT(BIT, MIN(CONVERT(INT, BitField))) as BitField

2

AVG (CAST (boolean_column AS FLOAT)) HẾT (...) AS BOOLEAN_AGGREGATE

Cho một boolean mờ:

  • 1 cho biết đó là tất cả Đúng;

  • 0 cho biết đó là tất cả sai;

  • một giá trị giữa] 0..1 [cho biết khớp một phần và có thể là một phần trăm sự thật.

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.