Инструмент, чтобы узнать, почему выбор SQL не возвращает никаких данных - PullRequest
2 голосов
/ 18 ноября 2008

Существует ли инструмент, который говорит вам (или дает подсказку), почему конкретный оператор выбора не возвращает никаких строк, учитывая текущие данные в вашей базе данных.

например, если у вас было 4 следующих соединения таблицы

select * 
from a, b, c, d
where a.b_id = b.id
and b.c_id = c.id
and c.d_id = d.id

Если бы были строки, удовлетворяющие условию a.b_id = b.id, а также строки, удовлетворяющие условию b.c_id = c.id, но не было строк, удовлетворяющих условию c.d_id = d.id, это выделило бы c.d_id = d.id как проблема.

Т.е. Это может привести к нарушению предложения where и выяснить, какое из подусловий вернуло true, и выделить те, которые не вернули true.

Это не будет хорошо работать для сложных запросов, но многие операторы select являются простыми объединениями множества таблиц.

Это может быть полезно при создании тестовых данных для проверки кода приложения или отладки проблемы с работающей системой.

Графические инструменты объяснения (которые показывают план фактического пути выхода) приближаются, но они показывают слишком много информации и не выделяют отсутствующую ссылку в выбранной сцене.

Я использую postgres, sqllight и mysql, но мне было бы интересно узнать, как работают инструменты для других баз данных / платформ.

Меня также интересуют любые техники манула.

Кто-нибудь еще имеет эту проблему?

Кому-нибудь будет интересно, если я напишу такой инструмент?

Ответы [ 5 ]

12 голосов
/ 18 ноября 2008

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

В вашем случае

SELECT *
FROM a -- First run just to here, are there records?
INNER JOIN b
    ON a.b_id = b.id -- Then run just to here, is it OK?
INNER JOIN c
    ON b.c_id = c.id -- Then run just to here, is it OK?
INNER JOIN d
    ON c.d_id = d.id -- Then run just to here, is it OK?
2 голосов
/ 18 ноября 2008

Самого инструмента для этого не существует, потому что, как отмечали другие авторы, достаточно просто выделять последовательно большие части запроса (если он хорошо отформатирован, с одним предложением ANDed на строку). и посмотрите, сколько записей возвращено. Делать соединения явными здесь очень важно, потому что, скорее всего, именно здесь вы теряете строки, а не предложения WHERE.

Однако я вижу, что это интересный мини-инструмент: брать SQL-запрос с n предикатами в качестве входных данных и возвращать график результата подсчета после добавления каждого отдельного предложения AND в хобот оператора ... что-то как:

part           count
-------------- -------------
TRUNK          100
AND clause 1   90
AND clause 2   85
...            ...
AND clause n   20

SQL Management Studio может предложить способы подключения небольшого инструмента, подобного этому, в качестве макроса, который, возможно, стоит изучить. Отправьте это здесь, если вы делаете! :)

1 голос
/ 18 ноября 2008

Я бы обычно использовал подход , описанный Cade Roux

Но теоретически вы можете использовать следующий запрос:

SELECT a.id, b.id, c.id, d.id
FROM a 
LEFT JOIN b
    ON a.b_id = b.id
LEFT JOIN c
    ON b.c_id = c.id
LEFT JOIN d
    ON c.d_id = d.id

Строки, которые возвращают все значения NULL, указывают на таблицу без соответствующих данных. Например. если бы все c.id были нулевыми, это означало бы, что в таблице c нет соответствующих записей.

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

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

1 голос
/ 18 ноября 2008

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

1 голос
/ 18 ноября 2008

Это поможет вам начать ...

выберите количество (1) из a, b, где a.b_id = b.id

выберите количество (1) из b, c, где b.c_id = c.id

выберите количество (1) из c, d, где c.d_id = d.id

Обратите внимание, что вы используете AND, поэтому совпадение вышеперечисленных запросов может не соответствовать вашим ожиданиям.

OR

Использование MS-SQL Server Management Studio ... Откройте «План выполнения» и наведите указатель мыши на узлы «Фактическое количество строк».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...