2010-02-02 40 views
12

Tôi có một hệ thống Joomla và tôi đang cố gắng thay đổi tìm kiếm để nó tìm đúng các giá trị dấu phảy động trong cơ sở dữ liệu.Kiểm tra sự bình đẳng trên một trường float MySQL

Vì vậy, tôi có một truy vấn mà được xây dựng trong thời gian chạy mà trông giống như sau:

select 'column1' 
from 'some_table' 
where 'some_float_field' <=> '2.18' 

này không hoạt động, nó không bao giờ phù hợp với bất cứ điều gì, thậm chí mặc dù tôi thấy bản ghi trong db với giá trị này đó.

Vì vậy, tôi cố gắng chỉ làm điều này thay vì:

select 'column1' 
from 'some_table' 
where 'some_float_field' <=> 2.18 

Không may mắn, vì vậy sau đó tôi đã cố gắng đúc đến một chữ số thập phân (float không hoạt động đối với một số lý do), vì vậy tôi cố gắng này:

select 'column1' 
from 'some_table' 
where 'some_float_field' <=> CAST('2.18' AS DECIMAL(20, 2)) 

Không xúc xắc ...

Hãy ghi nhớ rằng> = hoặc < = trả về kết quả đúng đắn, chỉ < => mang lại cho tôi vấn đề này.

Làm cách nào để tôi có được sự bình đẳng khi làm việc ở đây?

Trả lời

12

Thông thường với các loại câu hỏi rất tốt để cung cấp một ví dụ nhỏ để tái tạo kết quả của bạn.

Thường kiểm tra các giá trị float chính xác là một ý tưởng tồi vì độ chính xác của dấu phẩy động không phải là một khoa học chính xác. Nó tốt hơn nhiều để sử dụng một số khoan dung.

create table foo1 (col1 float); 

insert into foo1 values (2.18); 
select * from foo1 where abs(col1-2.18) <= 1e-6 
+0

Vâng trong trường hợp này, tôi thực sự đang cố gắng tìm một "trọng lượng" của một cái gì đó mà người dùng đang đưa vào, nhưng họ muốn khớp chính xác các con số, vì vậy tôi phải đáp ứng yêu cầu. – Joseph

+2

Có yêu cầu người dùng để có một kiểu dữ liệu nổi trong bảng không? Thông thường, khi người dùng muốn các số thập phân chính xác (e. G. Money), kiểu dữ liệu thập phân là một lựa chọn tốt hơn nhiều. Bạn sẽ nhận được các vấn đề làm tròn trong nhiều năm tới. Nghĩ về nó. Và nếu nó thực sự là tiền, bởi bất kỳ cơ hội, lãng phí không có thời gian và thiết kế lại cho thập phân NGAY BÂY GIỜ. Tin tôi đi, tôi nói từ kinh nghiệm ở đây. –

+0

Tôi đồng ý với Seva. Việc đầu tiên tôi làm trước khi bắt đầu làm việc trên một cơ sở dữ liệu mới là chạy truy vấn sau và tìm thấy có bao nhiêu cột phao được sử dụng. SELECT DATA_TYPE, COUNT (*) AS số tiền của tôi TỪ thông tin_schema.COLUMNS WHERE TABLE_SCHEMA KHÔNG IN ('information_schema', 'mysql') GROUP BY DATA_TYPE ORDER BY mycount DESC Nếu tôi thấy rằng số lượng gấp đôi, float, bigint và blobs là quá cao thì tôi cho rằng sẽ có rất nhiều vấn đề. Nếu số thập phân, ngày tháng, ngày giờ, tinyint quá nhỏ (hoặc nill) thì lại có vấn đề :) – shantanuo

1

Hãy xem xét điều này:

where abs(some_float_field) - 2.18 < 0.001 
+0

Tôi hiểu vấn đề chính xác. Trong trường hợp của tôi, tôi không quan tâm về độ chính xác qua vị trí thập phân thứ 2. Tôi chỉ muốn tìm thấy bất cứ điều gì phù hợp, tôi không tìm cách làm bất kỳ số học. – Joseph

4

Tôi tìm cách kiểm tra xem người dùng của tôi xem là bình đẳng.

tôi đã phải chuyển đổi lĩnh vực này để một chuỗi ký tự và kiểm tra các bộ ký tự, vì vậy đây hoạt động tốt đối với họ:

select 'column1' 
from 'some_table' 
where CAST('some_float_field' AS CHAR) <=> '2.18' 
0

Tôi biết những là một bài cũ nhưng nếu bạn không muốn có một chính xác so sánh chỉ sử dụng LIKE hoặc NOT LIKE:

select 'column1' 
from 'some_table' 
where 'some_float_field' NOT LIKE '2.18' 
+0

Đó là so sánh chuỗi! Nó cũng trả về các hàng như '12.18', v.v. – xmedeko

+0

@xmedeko tác giả yêu cầu tìm cách lấy tất cả các giá trị không bằng 2,18. Ngay cả khi nó là một chuỗi so sánh 12,18 là không bằng 2,18 vì vậy không có vấn đề để trả lại 12,18. Ngoài ra nếu bạn nhìn gần hơn với truy vấn của tôi, bạn sẽ nhận thấy rằng tôi không sử dụng dấu phần trăm và lý do tại sao 12.18 là một giá trị chính xác để trả về. – Shaolin

+0

@xmedeko không có gì để chỉnh sửa. Nếu bạn muốn chỉ nổi bằng 2,18 sau đó chỉ cần sử dụng LIKE mà không có dấu% và nó sẽ chỉ lấy 2,18. 'tạo thử nghiệm bảng (float giá) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB; chèn vào các giá trị thử nghiệm (2.18), (12.18), (32.18); SELECT * FROM test where price LIKE '2.18';' – Shaolin

Các vấn đề liên quan