Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
# Пример на php (прочие языки таковы же)
ustimenko@home:~$ php -r 'var_dump((1 - 0.7) == 0.3);'
bool(false)
# Ибо
ustimenko@home:~$ php -d precision=32 -r 'var_dump((1 - 0.7), 0.3);'
float(0.30000000000000004440892098500626)
float(0.29999999999999998889776975374843)
1.9.3p327 :007 > BigDecimal.new(1, 2) - BigDecimal.new(0.7, 2) == BigDecimal.new(0.3, 2)
=> true
1.9.3p327 :008 > 1 - 0.7 == 0.3
=> false
1.9.3p327 :021 > Rational(0.55)
=> (2476979795053773/4503599627370496)
BigDecimal.new(1, 2) - BigDecimal.new(0.7, 2) == BigDecimal.new(0.2999, 2) # true
1.9.3p327 :010 > Benchmark.measure { BigDecimal.new(1, 2) - BigDecimal.new(0.7, 2) == BigDecimal.new(0.3, 2) }
=> 0.000000 0.000000 0.000000 ( 0.000089)
1.9.3p327 :011 > Benchmark.measure { 1 - 0.7 == 0.3 }
=> 0.000000 0.000000 0.000000 ( 0.000015)
ustimenko@home:~$ ruby -e 'print(1 - 0.7 == 0.3); print("\n");'
false
ustimenko@home:~$ ruby -e 'require "bigdecimal"; print(BigDecimal.new("1") - BigDecimal.new("0.7") == BigDecimal.new("0.30000")); print("\n");'
true
ustimenko@home:~$ python -c 'print (1 - 0.7 == 0.3)'
False
python -c 'from decimal import *; print (1 - Decimal("0.7") == Decimal("0.3"))'
True
CREATE TABLE `medals` ( `id` int(11) NOT NULL AUTO_INCREMENT, `country` varchar(50) NOT NULL, `event_name` varchar(50) NOT NULL, `golds` int(11) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; INSERT into medals(event_name) VALUES('starting'); Select * from medals; +----+---------+------------+-------+ | id | country | event_name | golds | +----+---------+------------+-------+ | 3 | | starting | 0 | +----+---------+------------+-------+ 1 row in set (0.00 sec)
SELECT 124124/0; +----------+ | 124124/0 | +----------+ | NULL | +----------+ 1 row in set (0.00 sec)
mysql> SET sql_mode='STRICT_TRANS_TABLES,NO_ZERO_DATE,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO'; Query OK, 0 rows affected (0.00 sec) mysql> SELECT 124124/0; +----------+ | 124124/0 | +----------+ | NULL | +----------+ 1 row in set, 1 warning (0.00 sec) mysql> SELECT @@SESSION.sql_mode; +-----------------------------------------------------------------------------+ | @@SESSION.sql_mode | +-----------------------------------------------------------------------------+ | STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO | +-----------------------------------------------------------------------------+ 1 row in set (0.00 sec)
1.0 / 0.0 => Infinity
ну уж 65535 десятичных цифр — нам точно хватит
create table unlimited_table (new_bigint_field bigint(65535));
ERROR 1439 (42000): Display width out of range for column 'new_bigint_field' (max = 255)
show create table new_unlimited_table \G
*************************** 1. row ***************************
Table: new_unlimited_table
Create Table: CREATE TABLE `new_unlimited_table` (
`new_bigint_field` bigint(65535) NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
В MySQL нет таких извращений как в Oracle (там NULL равен пустой строке)
declare
a char := '';
begin
if a is null then
dbms_output.put_line( 'null' );
else
dbms_output.put_line( 'not null' );
end if;
end;
/
create or replace function f_is_null(s varchar2) return varchar2 is
type tt is table of number index by varchar2(10);
vt tt;
e exception;
pragma exception_init(e,-6502);
begin
vt(s):=1;
return case
when s is null then 'empty'
else 'not empty'
end;
exception
when e then return 'null';
end;
/
declare
pkey1 varchar2(10):='';
pkey2 varchar2(10):=null;
pkey3 varchar2(10):='filled';
begin
dbms_output.put_line('pkey1-'||f_is_null(pkey1));
dbms_output.put_line('pkey2-'||f_is_null(pkey2));
dbms_output.put_line('pkey3-'||f_is_null(pkey3));
end;
/
Я такого запроса категорически не понимаю! Что за группировка по второму полю, а дистинкт без агрегата по первому?select distinct int_value from null_equals_zero group by group_value;
Как вы понимаете данный запрос вернет нам уникальные значения первой колонки которых как мы знаем два: ноль и NULL
mysql> create table null_equals_zero(int_value int,
-> group_value int
-> )
-> engine = innodb;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into null_equals_zero
-> values (1, 1), (2, 1), (3, 1), (4, 1);
Query OK, 4 rows affected (0.00 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> select distinct int_value
-> from null_equals_zero
-> group by group_value;
+-----------+
| int_value |
+-----------+
| 1 |
+-----------+
1 row in set (0.00 sec)
drop table if exists null_equals_zero;
create table null_equals_zero(int_value int,
group_value int
)
engine = innodb;
insert into null_equals_zero
values (null, 1), (0, 2), (1, 3);
select distinct int_value
from null_equals_zero
group by group_value;
+-----------+
| int_value |
+-----------+
| NULL |
| 1 |
+-----------+
delete from null_equals_zero;
insert into null_equals_zero
values (0, 1), (null, 2), (1, 3);
select distinct int_value
from null_equals_zero
group by group_value;
+-----------+
| int_value |
+-----------+
| 0 |
| 1 |
+-----------+
Как вы понимаете данный запрос вернет нам уникальные значения первой колонки которых как мы знаем два: ноль и NULL
Я такого запроса категорически не понимаю! Что за группировка по второму полю, а дистинкт без агрегата по первому?
drop table if exists null_equals_zero;
create table null_equals_zero(int_value int,
group_value int
)
engine = innodb;
insert into null_equals_zero
values (1, 1), (0, 2), (1, 3), (0, 4);
select int_value
from null_equals_zero
group by group_value;
+-----------+
| int_value |
+-----------+
| 1 |
| 0 |
| 1 |
| 0 |
+-----------+
4 rows in set (0.00 sec)
select distinct int_value
from null_equals_zero
group by group_value;
+-----------+
| int_value |
+-----------+
| 1 |
| 0 |
+-----------+
2 rows in set (0.00 sec)
drop table if exists null_equals_zero;
create table null_equals_zero(int_value int,
group_value int
)
engine = innodb;
insert into null_equals_zero
values (null, 1), (0, 2), (null, 3), (0, 4);
select int_value
from null_equals_zero
group by group_value;
+-----------+
| int_value |
+-----------+
| NULL |
| 0 |
| NULL |
| 0 |
+-----------+
4 rows in set (0.00 sec)
select distinct int_value
from null_equals_zero
group by group_value;
+-----------+
| int_value |
+-----------+
| NULL |
+-----------+
1 row in set (0.00 sec)
Вы используете исключительно кривой запрос с багом.
select distinct int_value
from null_equals_zero
group by group_value;
SET sql_mode = 'ONLY_FULL_GROUP_BY';
SELECT distinct int_value
FROM null_equals_zero
group by group_value;
Error Code: 1055. 'test.null_equals_zero.int_value' isn't in GROUP BY
drop table if exists two_numbers;
create table two_numbers (
number_value enum('1','0')
);
insert into two_numbers(number_value)
values ('0'), ('1');
select concat(max(number_value), ' = ', max(number_value + 0)) one_equals_two from two_numbers;
+----------------+
| one_equals_two |
+----------------+
| 1 = 2 |
+----------------+
1 row in set (0.00 sec)
Sorting
ENUM values are sorted based on their index numbers, which depend on the order in which the enumeration members were listed in the column specification. For example, 'b' sorts before 'a' for ENUM('b', 'a'). The empty string sorts before nonempty strings, and NULL values sort before all other enumeration values.
To prevent unexpected results when using the ORDER BY clause on an ENUM column, use one of these techniques:
Specify the ENUM list in alphabetic order.
Make sure that the column is sorted lexically rather than by index number by coding ORDER BY CAST(col AS CHAR) or ORDER BY CONCAT(col).
Sorting ENUM values are sorted based on their index numbers,
Сортировка. ENUM значения сортируются на основании их номера индекса
enum('1','0')
select number_value, number_value 0
from two_numbers
order by number_value desc;
------ ------
| val | ord |
------ ------
| 0 | 2 |
| 1 | 1 |
------ ------
select min(number_value) min_val from two_numbers;
---------
| min_val |
---------
| 0 |
---------
1 row in set (0.00 sec)
А еще раз подумать:
MySQL: разрушаем стереотипы