1

Всякий раз, когда есть какое-либо описание запроса перед нами, мы пытаемся применить эвристику и мозговой штурм, чтобы построить запрос.Есть ли какое-либо эмпирическое правило для создания SQL-запроса из общепринятого для человека описания?

Есть ли систематический поэтапный или математический способ построения SQL-запроса из данного читаемого человеком описания?

Например, как определить, что, будет ли SQL-запрос необходимо объединение, а не подзапроса, будь то потребуется группа по, будь то потребуется пункт IN, и т.д ....

Например, кто бы ни изучал Digital Electronics, он бы знал о таких методах, как Karnaugh Map или Quin McClausky. Это некоторые системные подходы к упрощению цифровой логики.

Если есть какой-либо метод для анализа запросов sql вручную, чтобы избежать мозгового штурма каждый раз?

+0

Проверить [Реляционная алгебра] (https://en.wikipedia.org/wiki/Relational_algebra) – lad2025

+1

В каком формате должно содержаться это описание? Человеческий читаемый текст? – usr

+1

Есть кое-что, что вы можете сделать по-разному. Таким образом, выбор между подзапросом или объединением может делать то же самое, но в зависимости от db или данных может иметь разную производительность. –

ответ

1

Вот что я в не сгруппированных запросов:

я вкладываю в п FROM таблицу которого я ожидаю получить ноль или один выходной строки на строку в таблице. Часто вы хотите что-то вроде «всех клиентов с определенными свойствами». Затем таблица клиентов переходит в пункт FROM.

Используйте соединения, чтобы добавить столбцы и строки фильтров. Соединения не должны дублировать строки. Соединение должно найти нуль или один ряд, никогда больше. Это делает его очень интуитивным, потому что вы можете сказать, что «объединение добавляет столбцы и фильтрует некоторые строки».

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

Как использовать WHERE и проекции легко.

+0

Интересно, кто голосовал за этот вопрос, чтобы закрыть. – anonymous

+0

и как насчет сгруппированных запросов? – anonymous

+0

Для сгруппированных вопросов я бы сначала построил негруппированный. Затем добавление группировки довольно просто, потому что столбцы группировки - это те, которые вы хотите иметь по одной строке для каждой уникальной комбинации. Я думаю, что сложная часть - это объединение таблиц и объединение. Остальное рудное интуитивное. – usr

3

Есть ли систематический шаг за шагом или математическим способом построить SQL запроса из данного читабельного описания?

Да, есть.

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

Каждая таблица (результат базы или запроса) имеет связанный предикат - шаблон формулировки естественного языка для заполнения (named-), параметризованный именами столбцов.

-- person [liker] likes person [liked] 

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

liker | liked 
-------------- 
Bob | Dex -- Bob likes Dex 
Bob | Alice -- Bob likes Alice 
Alice | Carol -- Alice likes Carol 

Каждое предложение от заполнения предиката значениями из строки в таблице является истинным. И каждое предложение от заполнения предиката со значениями из строки не в таблице является ложным.

/* 
    Alice likes Carol 
AND NOT Alice likes Alice 
AND NOT Alice likes Bob 
AND NOT Alice likes Dex 
AND NOT Alice likes Ed 
... 
AND Bob likes Alice 
AND Bob likes Dex 
AND NOT Bob likes Bob 
AND NOT Bob likes Carol 
AND NOT Bob likes Ed 
... 
AND NOT Carol likes Alice 
... 
AND NOT Dex likes Alice 
... 
AND NOT Ed likes Alice 
... 
*/ 

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

-- person [liker] likes person [liked] 
-- Likes(liker, liked) 
SELECT * FROM Likes 

SQL-запрос выражение (суб) преобразует таблицы значений аргумента нового значения таблицы, удерживающее строку, которые делают истинное утверждение от нового предиката. Новый предикат таблицы может быть выражен в терминах предиката (ов) таблицы аргументов в соответствии с операторами реляционных/табличных выражений (sub). Мы пишем выражение SQL, предикат которого является предикатом для требуемой таблицы.

Внутри SELECT заявление, когда базовая таблица T с колоннами C,... имеет (возможно, неявно) псевдоним A мы можем рассматривать A в виде таблицы со значением T но с колоннами переименованы в A.C,.... (Мы можем использовать C для A.C, когда это однозначно.) Таким образом, предикат базовой таблицы с именем T с псевдонимом A - T(A.C,...). Предикат R CROSS JOIN S или R INNER JOIN S является предикатом RAND ed с предикатом S. Предикат R ON/WHEREcondition является предикатом RAND ред с condition. Предикат (...) IN R - R(...). SELECT DISTINCT пункт списка columns to keep таблицы ставит FOR SOME или THERE EXISTScolumns to drop перед его предиката. (Эти столбцы не являются параметрами полученного предиката.) A SELECT предложение переименовать столбец таблицы (возможно, с неявным A.) через AS переименовывает имя в свой предикат. (Это удаляет A. с.)

/* rows that make a true statement from 
FOR SOME l1.liked, l2.liker: 
     Likes(person, l1.liked) 
    AND Likes(l2.liker, liked) 
    AND l1.liked = l2.liker 
    AND person = 'Bob' 
    AND NOT Likes(person, 'Ed') 
*/ 
SELECT l1.liker AS person, l2.liked AS liked 
FROM 
    /* rows that make a true statement from 
     Likes(l1.liker, l1.liked) 
    AND Likes(l2.liker, l2.liker) 
    AND l1.liked = l2.liker 
    AND l1.liker = 'Bob' 
    AND NOT Likes(l1.liker, 'Ed') 
    */ 
Likes l1 INNER JOIN Likes l2 
ON l1.liked = l2.liker 
WHERE l1.liker = 'Bob' 
AND NOT (l1.liker, 'Ed') IN (SELECT * FROM Liker) 

Предикат R UNION CORRESPONDING S есть предикат ROR ред с предикатом S. Для R EXCEPT S мы используем AND NOT. VALUES(C,...)((V,...),...) имеет предикат (C = V AND ...) OR ....

/* rows that make a true statement from 
    FOR SOME liked, Likes(person, liked) 
OR person = 'Bob' 
*/ 
    SELECT liker AS person 
    FROM Likes 
UNION 
    VALUES (person) (('Bob')) 

Так что, если мы выражаем наши желательные строки в терминах данной базовой таблицы шаблонов выписок естественного языка, что строки делают истинные или ложные (должны быть возвращены или нет), то мы можем перевести на запросы SQL, которые вложения логического сокращения от & Операторы и/или имена таблиц & операторов. И тогда СУБД может полностью конвертироваться в таблицы для вычисления строк, что делает наш предикат истинным.

См. this Повторное применение этого к SQL и this для получения дополнительной информации о естественных языковых фразированиях.

+0

Хотя я не могу полностью с вами согласиться, это очень интересная точка зрения. – Ingaz

Смежные вопросы