группа sql по сравнению с отличным

Я написал эту небольшую функцию несколько лет назад:

function sqlvprintf($query, $args)
{
    global $DB_LINK;
    $ctr = 0;
    ensureConnection(); // Connect to database if not connected already.
    $values = array();
    foreach ($args as $value)
    {
        if (is_string($value))
        {
            $value = "'" . mysqli_real_escape_string($DB_LINK, $value) . "'";
        }
        else if (is_null($value))
        {
            $value = 'NULL';
        }
        else if (!is_int($value) && !is_float($value))
        {
            die('Only numeric, string, array and NULL arguments allowed in a query. Argument '.($ctr+1).' is not a basic type, it\'s type is '. gettype($value). '.');
        }
        $values[] = $value;
        $ctr++;
    }
    $query = preg_replace_callback(
        '/{(\\d+)}/', 
        function($match) use ($values)
        {
            if (isset($values[$match[1]]))
            {
                return $values[$match[1]];
            }
            else
            {
                return $match[0];
            }
        },
        $query
    );
    return $query;
}

function runEscapedQuery($preparedQuery /*, ...*/)
{
    $params = array_slice(func_get_args(), 1);
    $results = runQuery(sqlvprintf($preparedQuery, $params)); // Run query and fetch results.   
    return $results;
}

Это позволяет запускать операторы в однострочном C # -ish String.Format, например:

runEscapedQuery("INSERT INTO Whatever (id, foo, bar) VALUES ({0}, {1}, {2})", $numericVar, $stringVar1, $stringVar2);

Он избегает использования типа переменной. Если вы попытаетесь параметризовать имена таблиц и столбцов, это будет терпеть неудачу, поскольку она помещает каждую строку в кавычки, которая является недопустимым синтаксисом.

ОБНОВЛЕНИЕ БЕЗОПАСНОСТИ: предыдущая версия str_replace разрешала инъекции, добавляя токены {#} в пользовательские данные. Эта версия preg_replace_callback не вызывает проблем, если замена содержит эти токены.

38
задан Frank V 12 February 2011 в 04:28
поделиться

4 ответа

Немного (Очень небольших) эмпирических данных от SQL Server MS, на нескольких случайных таблицах от нашего DB.

Для шаблона:

SELECT col1, col2 FROM table GROUP BY col1, col2

и

SELECT DISTINCT col1, col2 FROM table 

, Когда нет никакого закрывающего индекса для запроса, оба пути произвели следующий план запросов:

|--Sort(DISTINCT ORDER BY:([table].[col1] ASC, [table].[col2] ASC))
   |--Clustered Index Scan(OBJECT:([db].[dbo].[table].[IX_some_index]))

и когда был закрывающий индекс, оба произведенные:

|--Stream Aggregate(GROUP BY:([table].[col1], [table].[col2]))
   |--Index Scan(OBJECT:([db].[dbo].[table].[IX_some_index]), ORDERED FORWARD)

так от того SQL Server очень небольшой выборки, конечно, рассматривает обоих то же.

18
ответ дан Cowan 27 November 2019 в 03:48
поделиться

GROUP BY группы карт строк к одной строке, на отличное значение в [1 112] конкретный столбцы, которые не должны даже обязательно быть в списке выборки.

SELECT b, c, d FROM table1 GROUP BY a;

Этот запрос является легальным SQL ( исправление: только в MySQL; на самом деле это не стандартный SQL и не поддерживаемое другими брендами). MySQL принимает его, и это полагает, что Вы знаете то, что Вы делаете, выбирая b, c, и d однозначным способом, потому что они функциональные зависимости из a.

Однако Microsoft SQL Server и другие бренды не позволяют этот запрос, потому что это не может определить функциональные зависимости легко. редактирование: Вместо этого стандартный SQL требует, чтобы Вы следовали Правило Единственного Значения, т.е. каждый столбец в списке выборки нужно или назвать в GROUP BY пункт или иначе быть аргументом функции множества.

принимая во внимание, что DISTINCT всегда взгляды на все столбцы в списке выборки, и только те столбцы. Это - распространенное заблуждение, которое DISTINCT позволяет Вам определять столбцы:

SELECT DISTINCT(a), b, c FROM table1;

Несмотря на круглые скобки, делающие DISTINCT, похожи на вызов функции, это не. Это - опция запроса, и отличное значение в любом из трех полей списка выборки приведет к отличной строке в результате запроса. Одно из выражений в этом списке выборки имеет круглые скобки вокруг этого, но это не будет влиять на результат.

29
ответ дан Bill Karwin 27 November 2019 в 03:48
поделиться

Оба генерировали бы тот же план запросов в SQL Server MS.... Если у Вас есть SQL Server MS, Вы могли бы просто позволить фактическому плану выполнения видеть, какой лучше для Ваших потребностей...

взгляните на те сообщения:

http://blog.sqlauthority.com/2007/03/29/sql-server-difference-between-distinct-and-group-by-distinct-vs-group-by /

http://www.sqlmag.com/Article/ArticleID/24282/sql_server_24282.html

2
ответ дан Andre Gallo 27 November 2019 в 03:48
поделиться

При реальном поиске отличных значений отличное делает исходный код более читаемым (как то, если это будет часть хранимой процедуры), Если я запишу специальные запросы, я буду обычно запускать с группы, даже если у меня не будет агрегирований, потому что я буду часто заканчивать тем, что ставил их.

0
ответ дан Booji Boy 27 November 2019 в 03:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: