Есть ли лучший способ сделать запрос, подобный этому:
SELECT COUNT(*)
FROM (SELECT DISTINCT DocumentId, DocumentSessionId
FROM DocumentOutputItems) AS internalQuery
Мне нужно посчитать количество отдельных элементов из этой таблицы, но количество разных элементов превышает два столбца.
Мой запрос работает нормально, но мне было интересно, смогу ли я получить окончательный результат, используя только один запрос (без использования подзапроса)
sql
sql-server
performance
tsql
query-optimization
Novitzky
источник
источник
Ответы:
Если вы пытаетесь улучшить производительность, вы можете попытаться создать постоянный вычисляемый столбец для хеш-значения или объединенного значения двух столбцов.
Как только он сохраняется, при условии, что столбец является детерминированным, и вы используете «нормальные» настройки базы данных, он может быть проиндексирован и / или может быть создана статистика для него.
Я считаю, что отдельный счет вычисляемого столбца будет эквивалентен вашему запросу.
источник
Изменить: Изменено из менее надежного запроса только контрольной суммы, я обнаружил способ сделать это (в SQL Server 2005), который работает довольно хорошо для меня, и я могу использовать столько столбцов, сколько мне нужно (добавляя их в функция CHECKSUM ()). Функция REVERSE () превращает целые числа в varchars, чтобы сделать их более надежными
источник
Что вам больше не нравится в существующем запросе? Если вы обеспокоены тем, что
DISTINCT
по двум столбцам не возвращается только уникальная перестановка, почему бы не попробовать?Это, безусловно, работает, как и следовало ожидать в Oracle.
редактировать
Я пошел в тупик с аналитикой, но ответ был удручающе очевиден ...
редактировать 2
С учетом следующих данных приведенное выше объединенное решение будет неверно учтено:
Поэтому мы должны включить разделитель ...
Очевидно, что выбранный разделитель должен быть символом или набором символов, которые никогда не могут появляться ни в одном столбце.
источник
Чтобы выполнить один запрос, объедините столбцы, а затем получите различное количество экземпляров объединенной строки.
В MySQL вы можете сделать то же самое без этапа объединения следующим образом:
Эта функция упоминается в документации MySQL:
http://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html#function_count-distinct
источник
SELECT COUNT(DISTINCT (DocumentId, DocumentSessionId)) FROM DocumentOutputItems;
Как насчет чего-то вроде:
Вероятно, просто делает то же самое, что вы уже сделали, но это избегает ОТЛИЧИЯ.
источник
GROUP BY
может создать пару дополнительных проблем для преобразования запроса для достижения желаемого результата (например, когда исходный запрос уже имелGROUP BY
илиHAVING
содержит предложения ...)Вот более короткая версия без подвыбора:
Он прекрасно работает в MySQL, и я думаю, что оптимизатору легче понять это.
Изменить: Очевидно, я неправильно прочитал MSSQL и MySQL - извините за это, но, возможно, это все равно помогает.
источник
count ( distinct CHECKSUM ([Field1], [Field2])
Многие (большинство?) Базы данных SQL могут работать с кортежами, такими как значения, так что вы можете просто сделать:
SELECT COUNT(DISTINCT (DocumentId, DocumentSessionId)) FROM DocumentOutputItems;
если ваша база данных не поддерживает это, она может быть смоделирована в соответствии с предложением @ Oncel-umut-turer CHECKSUM или другой скалярной функции, обеспечивающей хорошую уникальность напримерCOUNT(DISTINCT CONCAT(DocumentId, ':', DocumentSessionId))
.Связанное использование кортежей выполняет
IN
такие запросы:SELECT * FROM DocumentOutputItems WHERE (DocumentId, DocumentSessionId) in (('a', '1'), ('b', '2'));
источник
select count(distinct(a, b))
? : DВ вашем запросе нет ничего плохого, но вы также можете сделать это следующим образом:
источник
Надеюсь, что это работает, я пишу на Prima Vista
источник
Я использовал этот подход, и он сработал для меня.
Для моего случая это дает правильный результат.
источник
если у вас есть только одно поле для «DISTINCT», вы можете использовать:
и он возвращает тот же план запроса, что и исходный, как было проверено с помощью SET SHOWPLAN_ALL ON. Однако вы используете два поля, чтобы вы могли попробовать что-то сумасшедшее, например:
но у вас будут проблемы, если участвуют NULL. Я бы просто придерживался оригинального запроса.
источник
Я обнаружил это, когда гуглил по своей собственной проблеме, обнаружил, что если вы посчитаете объекты DISTINCT, вы получите верное правильное число (я использую MySQL)
источник
DocumentId
иDocumentSessionId
). Александр Кьялл уже опубликовал правильный ответ, если OP использовал MySQL, а не MS SQL Server.Я хотел бы, чтобы MS SQL мог также делать что-то вроде COUNT (DISTINCT A, B). Но это не может.
Сначала ответ JayTee показался мне решением, но после некоторых тестов CHECKSUM () не смог создать уникальные значения. Быстрый пример: и CHECKSUM (31 467 519), и CHECKSUM (69,11 8 823) дают один и тот же ответ - 55.
Затем я провел небольшое исследование и обнаружил, что Microsoft НЕ рекомендует использовать CHECKSUM для целей обнаружения изменений. На некоторых форумах некоторые предлагали использовать
но это тоже не обнадеживает.
Вы можете использовать функцию HASHBYTES (), как предложено в головоломке TSQL CHECKSUM . Однако это также имеет небольшой шанс не вернуть уникальные результаты.
Я бы предложил использовать
источник
Как насчет этого,
Это даст нам счет всех возможных комбинаций DocumentId и DocumentSessionId.
источник
Меня устраивает. В оракуле
В jpql:
источник
У меня был похожий вопрос, но у меня был подзапрос с данными сравнения в основном запросе. что-то вроде:
игнорируя сложности этого, я понял, что не могу получить значение a.code в подзапрос с двойным подзапросом, описанным в исходном вопросе
В итоге я понял, что могу обмануть и объединить столбцы:
Это то, что в конечном итоге работает
источник
Если вы работаете с типами данных фиксированной длины, вы можете использовать это,
binary
чтобы сделать это очень легко и очень быстро. Предполагая ,DocumentId
иDocumentSessionId
обаint
s, и поэтому 4 байтам ...Моя конкретная проблема требует , чтобы я разделить
SUM
наCOUNT
из отдельной комбинации различных внешних ключей и поля даты, группируя другой внешним ключом , а иногда фильтрации определенных значений или ключами. Таблица очень большая, и использование подзапроса значительно увеличило время запроса. И из-за сложности, статистика просто не была жизнеспособным вариантом.CHECKSUM
Решение было также слишком медленно его преобразования, в частности , в результате различных типов данных, и я не мог рисковать своей ненадежности.Однако использование вышеуказанного решения практически не увеличивает время запроса (по сравнению с использованием просто
SUM
) и должно быть абсолютно надежным! Это должно быть в состоянии помочь другим в подобной ситуации, поэтому я публикую это здесь.источник
Вы можете просто использовать функцию подсчета дважды.
В этом случае это будет:
источник
Этот код использует отличные по 2 параметрам и обеспечивает подсчет количества строк, специфичных для этих разных значений. Это работало для меня в MySQL как очарование.
источник