SQL въпрос (към колеги програмисти)
November 19, 2007
Може ли да ми кажете, защо тази заявка връща 1, а не грешка? Пуля се тук защо една ултраважна заявка не ми работи, а аз съм изтървал напрактика ВСИЧКО В НЕЯ =)
mysql> select count(*) as c;
+---+
| c |
+---+
| 1 |
+---+
1 row in set (0.67 sec)
Пействам го от MySQL, но в SQL Server е същото, та предполагам това е обичайният начин, по който трябва да работи.
Ето допълнение:
mysql> select *;
ERROR 1096 (HY000): No tables used
MS SQL:
select *
Server: Msg 263, Level 16, State 1, Line 1
Must specify table to select from.
Публикувано в: Гърнето с боба 16 коментара
RSS 2.0
Ако постът ви харесва, цъкнете на сърцето:
Коментари
16 коментара на “SQL въпрос (към колеги програмисти)”
Оставете отговор

Ми като го пуснеш в някоя база данни (примерно 9i, 10g, 11g
) не работи и си дава нормалното и очаквано съобщение за грешка.
А какво ти показва explain plan или както там се казва в mysql и ms sql server?
Нещо не виждам FROM клаузата.
SELECT count(*)
FROM table_name
select count(5); също връща 1, така че вероятно е нормално агрегатна функция да върне такъв резултат.
от друга страна select count(null) връща 0
явно всичко опира до това, как звездичката се интерпретира от count
Объркването идва от “интуитивното” определение, че “*” в COUNT означава нещо като “кое-да-е”, “всички” (ала “rm -rf *”)
Изглежда, че COUNT(*) е “по-специален” – взето от manual-a:
“COUNT(*) is somewhat different in that it returns a count of the number of rows retrieved, whether or not they contain NULL values.”
SQL позволява изрази от вида “SELECT 1+1″, които винаги връщат 1 ред, следователно SELECT COUNT(1+1) отново е 1 (“един върнат ред като резултат”). Само, че SELECT COUNT(NULL) е 0 защото:
“COUNT(expr) returns a count of the number of non-NULL values of expr in the rows retrieved by a SELECT statement”.
Ето един по дълъг пример:
mysql> select COUNT(t) FROM (SELECT NULL as t) as t2;+----------+
| COUNT(t) |
+----------+
| 0 |
+----------+
1 row in set (0.00 sec)
mysql> select COUNT(*) FROM (SELECT NULL as t) as t2;
+----------+
| COUNT(*) |
+----------+
| 1 |
+----------+
1 row in set (0.00 sec)
Не е ли забавен SQL?
Даниел, има Execution plan, който връща следната последователност (към всяко има подробности, които не ни касаят особено).
Constant scan: 92%
Stream aggregate: 8%
Compute scalar: 0%
SELECT: 0%
Constant Scan Showplan Operator
The Constant Scan operator introduces one or more constant rows into a query. A Compute Scalar operator is often used after a Constant Scan to add columns to a row produced by the Constant Scan operator.
т.е. не знаем защо го прави, но знаем как го прави
@Свилен: това само прави нещата по-странни
@SuperCow: правилно си забелязала, за това става въпрос в поста.
@Даниел explain в mysql прави друго, не връща полезна информация в случая.
Ми предполагам, че са решили да ти спестят писането на това from (select null as t) и за това…
типично в sql стил ми изглежда select count(*) без from да върне 1
Ми …
mysql> select count(*) as c;
+—+
| c |
+—+
| 0 |
+—+
1 row in set (0.02 sec)
mysql> select version();
+————-+
| version() |
+————-+
| 5.0.24a-log |
+————-+
1 row in set (0.01 sec)
Ми (x2):
mysql> select count(*) as c;
+—+
| c |
+—+
| 1 |
+—+
1 row in set (0.01 sec)
mysql> select version();
+————————-+
| version() |
+————————-+
| 5.0.37-community-nt-log |
+————————-+
1 row in set (0.00 sec)
@Свилен
Ти уби всичко детско в мен…
и аз:
mysql> select count(*) as c;
+—+
| c |
+—+
| 1 |
+—+
1 row in set (0.00 sec)
mysql> select version();
+—————–+
| version() |
+—————–+
| 4.1.22-standard |
+—————–+
1 row in set (0.00 sec)
ако “COUNT(*) is somewhat different in that it returns a count of the number of rows retrieved, whether or not they contain NULL values.” то за да изведе въобще някакъв резултат, sql-а ще избълва един row. по тази логика излиза редно резултатът да е 1, а не 0. идея си нямам 5.0.24a-log как я докарва тая 0. но изглежда като оптимизация за скорост. във всеки случай не мога да измисля какъв трик се опитваш да извършиш с участието на точно тая заявка
минете на орацле – по-добрата боза
При мен:
mysql> select count(*) as c;
+—+
| c |
+—+
| 0 |
+—+
1 row in set (0.00 sec)
Странно би било да е 1
И разбира се …
mysql> select version();
+———–+
| version() |
+———–+
| 5.0.18-nt |
+———–+
1 row in set (0.00 sec)