Вы на НеОфициальном сайте факультета ЭиП

На нашем портале ежедневно выкладываются материалы способные помочь студентам. Курсовые, шпаргалки, ответы и еще куча всего что может понадобиться в учебе!
Главная Контакты Карта сайта
 
Где мы?

Реклама


Лекции по SQL. Часть 1.

Просмотров: 1692 Автор: admin

Лекции по <!--[if gte mso 9]> Normal 0 false false false MicrosoftInternetExplorer4 SQL

1.Архитектура клиент - сервер

Клиентом и сервером мы будем называть процессы (программы и приложения), работающие одновременно на  одном или разных компьютерах (объединенных в сеть). Клиент посылает серверу запрос на получение данных или на выполнение какой-то работы. В частности это может быть запрос к серверу баз данных, например к SQL - серверу. Сервер, получив от клиента запрос, выполняет соответствующие действия и посылает клиенту ответ. Например, сервер баз данных находит нужные записи и посылает из клиенту.

Транзакцией называется совокупность трех действий: посылка запроса, его выполнение и прием ответа. Транзакция называется завершенной, если выполнены все три действия. Если одно из действий осталось невыполненным, транзакция является незавершенной. Для незавершенных транзакций должен быть выполнен откат. Например, если сервер получил задание на модификацию группы записей БД, но до сбоя выполнил лишь часть работы, то откат заключается в восстановлении состояния базы данных на момент начала транзакции.

Основным преимуществом, которым обладают СУБД, базирующиеся на архитектуре клиент - сервер является уменьшение объема данных, передаваемых по сети. Действительно, для файл - серверной СУБД простая операция “найти запись по индексу” приведет к чтению и передаче по сети быть очень многих узлов В-дерева индекса, в то время, как в архитектуре клиент - сервер записи индекса по сети не передаются - поиск выполняется на сервере, а клиент получает лишь окончательный результат. Еще более разительным будет их различие для плохо структурированных и заранее непредусмотренных запросов типа: “найти легковой автомобиль ВАЗ или ГАЗ зеленого цвета одна из цифр номера которого - 7”. В этом примере трудно надеяться, что существуют индексы, которые бы позволили не читать в БД записи, не являющиеся целью запроса. Видимо, придется прочитать всю БД и для каждой записи принять решение - нужна ли она нам. В архитектуре клиент - сервер решение будет приниматься на сервере и посторонние записи по сети передаваться не будут.

Еще одно достоинство, сопутствующее архитектуре клиент - сервер это повышение надежности как программ, так и баз данных.

Не следует, однако думать, что СУБД клиент - сервер предпочтительны во всех случаях жизни. Для конфигураций сетей с небольшим числом станций или не слишком интенсивным траффиком в сети применение архитектуры клиент - сервер приведет только к удорожанию как программных, так и аппаратных средств.

Рассматриваемый ниже язык SQL (Structured Query Language) в настоящее время является основным языком, используемым в СУБД, основанных на архитектуре клиент - сервер. Это язык высокого уровня, основной единицей манипулирования в котором является не запись, а отношение. Его можно рассматривать как одну из реализаций реляционного исчисления. Использование SQL вовсе не обязательно предполагает архитектуру клиент - сервер, но архитектура клиент - сервер обязательно предполагает использование языка запросов типа SQL.

Как и любой язык высокого уровня он имеет и преимущества и недостатки. Преимуществом является лаконичность и простота формулирования сложных запросов,  ограничений целостности, уровней полномочий и т.п. Недостаток тот, что план выполнения запроса - функция драйвера, который, как правило, значительно “глупее” среднего программиста. В частности, для SQL-СУБД понятие индекса есть понятие уровня реализации, а не концептуальное и драйверы баз данных далеко не всегда разумно распоряжаются индексами для навигации в базе данных.

2. SQL - структурированный язык запросов

 

2.1.Базовая таблица

Базовая таблица - специальный случай более общего понятия “таблица”. Таб­лица - аналог отношения. Базовая таблица существует сама по себе в отличие от VIEW, которое может быть производным от многих таблиц. Не предполагается ни­какого упорядочения строк таблицы, но столбцы упорядочены.

 

2.2. База данных примера.

В примерах будет использована база данных, содержащая от­но­шения  (таб­­ли­цы):

Таблица S // поставщики

      NP     CHAR(5)  // Номер поставщика

      FAM    CHAR(20) // Фамилия поставщика

      STATUS SMALLINT // Статус поставщика

      CITY   CHAR(15) // Город, где находится поставщик

Каждый поставщик находится в одном городе

Таблица P  // Детали

      ND     CHAR(6)  // Номер детали

      D_NAME CHAR(20) // Название детали

      COLOR  CHAR(7)  // Цвет

      WEIGHT SMALLINT // Вес

      CITY   CHAR(15) // Город,  где находится деталь.

    Каждая деталь имеет один цвет и находится в единственном  городе.

Таблица SP // Поставки деталей поставщиками

      NP     CHAR(5) // Номер поставщика

      ND     CHAR(6) // Номер детали

      AMOUNT INTEGER // Количество деталей

 

2.3. CREATE TABLE

    CREATE TABLE  <имя> (определение столбца [,определение столбца]...);  , где <определение столбца> имеет вид:

 

    <Имя столбца> <тип>[(Width [,Decimals] )] [NOT NULL]

 

В результате выполнения команды

CREATE TABLE S (A char(5),B char(12))

будет создана таблица xyz.S с соответствующими  столбцами.  Здесь xyz - имя,  под  ко­то­рым известен системе пользователь,  создающий таблицу. NOT NULL  означает недо­пустимость неопределенных значений для элементов столбца.

 

Типы столбцов могут принимать значения:

INTEGER (int C)

SMALLINT (signed char C)

DECIMAL(p,q) 0<p<16; q<p

FLOAT (float C)

CHAR(n)

REAL

VARCHAR(n) - строка не > n литер, максимальное значение индивидуально для СУБД, зачастую=254

LONGVARCHAR - до 64kB

Столбец, который  может  принимать  неопределенные   значения сопро­вож­­дается бай­том - признаком неопределенного значения. В различных реали­за­циях и стандартах SQL могут существовать и другие типы. Они будут отобра­же­ны некоторым образом на фор­ма­ты данных конкретной СУБД. Такое отобра­же­ние является функцией драйвера.

 

2.4. ALTER TABLE

ALTER TABLE <имя таблицы> ADD <имя столбца> <тип>

 

По ALTER TABLE не происходит физического расширения всех имеющихся записей. Изменяется лишь хранимое в каталоге описание таблицы.  Отдельные за­­­пи­си не изме­нят­­ся, пока они не станут целевыми для предложения UPDATE.

 

2.5.  DROP TABLE

DROP <имя таблицы> - уничтожить таблицу. Таблица  удаляется из БД (или  из ката­лога удаляется ее описание, если драйвер поддерживает каталог); Авто­ма­ти­­чески удаляются все индек­сы и представ­ле­ния, определенные над таблицей.

 

2.6. Индексы

Создание:

CREATE [UNIQUE] INDEX <имя индекса>

ON <имя таблицы> (<имя столбца>[упорядочение]

[<имя столбца>[упорядочение]]...) [другие параметры];

 

Упорядочение может принимать значение ASC или DESC, что означает воз­рас­та­ю­щий или убывающий порядок. Два неопределенных  значения считаются равными с точ­ки зрения их вхождения в индекс.

Индекс уничтожается оператором

DROP INDEX <имя индекса>

Некоторые СУБД способны создавать хеш - индексы.

В SqlWindows:

CREATE [UNIQUE] CLUSTERED HASHED INDEX <Имя индекса>

ON <Имя таблицы> SIZE <число> ROWS;

Если нет подходящих индексов, то эффективность может оказаться очень низкой.

 

2.7. Манипулирование данными.

2.7.1.    Оператор SELECT.

 

Общий вид оператора SELECT:

 

SELECT <поля>     FROM <таблица(ы)>    WHERE <предикат>

 

Более конкретно (за исключением UNION и FOR UPDATE):

 

SELECT [DISTINCT] элемент(ы)

FROM <таблица(ы)>

[WHERE <предикат>]

[GROUP BY <поле(я)> [HAVING <предикат>]]

[ORDER BY <поле(я)>]

 

DISTINCT - не помещать в результат дубликаты.

Элемент в общем случае может быть выражением, например:

 

SELECT ND, "Вес в граммах=", WEIGHT*454 FROM  P;

 

Оператор SELECT * FROM P; означает выборку всех полей. Любое выра­же­ние име­ет неопределенное значение, если его имеет один из операндов.

Фраза ORDER означает упорядочение: ...ORDER BY x ASC,y DESC

 

Фраза BETWEEN может являться частью предиката:

                ...WHERE WEIGHT BETWEEN 16 AND 19

 

Фраза IN: ...WHERE WEIGHT IN (12,16,17) означает, что вес может прини­мать одно из трех  значений.

 

Предикат LIKE. ...WHERE D_NAME LIKE "c%"

 

Сравнение неопределенного значения с чем угодно и  как угодно дает "ложь".  Для запроса неопределенных значений существует предикат:

 

                                    <имя поля> IS [NOT] NULL

 

Пример простой выборки:

SELECT NP FROM S WHERE s.city='Париж' and s.status>20;

 

Выборка с упорядочением:

SELECT NP,status FROM s WHERE city='Лондон' ORDER BY status ASC;

 

2.7.2.    Соединение.

    Простое соединение:

    SELECT S.*, P.* FROM S,P WHERE S.CITY=P.CITY

Соединение можно  выполнить  по  любому предикату и для более чем

двух  таблиц.

Можно упростить до:

SELECT * FROM S,P...

Это уже декартово произведение.

Пример соединения трех таблиц:

Выдать все пары названий городов таких,  что поставщик, находящийся в первом горо­де поставляет деталь,  находящуюся  во втором городе.

 

SELECT DISTINCT s.city, p.city FROM s,sp,p

WHERE s.np=sp.np AND sp.nd=p.nd;

 

2.7.3.    Внешнее соединение (как в ACCESS 97)

Внешнее соединение объединяет записи исходных таблиц при использовании в любом предложении FROM.

Синтаксис

FROM таблица_1 [ LEFT | RIGHT ] JOIN таблица_2

ON таблица_1.поле_1 оператор таблица_2.поле_2


Ниже перечислены аргументы операций LEFT JOIN и RIGHT JOIN:

Элемент       Описание

таблица_1,

таблица_2             Имена таблиц, записи которых подлежат объединению.

поле_1, поле_2      Имена объединяемых полей.  Поля должны иметь одинаковый тип       

                                данных и содержать данные одного рода, однако, могут иметь      

                                разные имена.

оператор              Любой оператор сравнения: "=," "<," ">," "<=," ">=," или "<>".

 

Дополнительные сведения

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

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

 

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

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

 

SELECT Категория,

Марка

FROM Типы LEFT JOIN Товары

ON Типы.КодТипа = Товары.КодТипа;

 

В предыдущем примере поле "КодТипа" используется для объединения таблиц, однако, не включается в результат выполнения запроса, поскольку не включено в инструкцию SELECT.  Чтобы включить связующее поле (в данном случае поле Типы.КодТипа) в результат выполнения запроса, включите имя этого поля в инструкцию SELECT.

Примечания

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

           Операции LEFT JOIN или RIGHT JOIN могут быть вложены в операцию INNER JOIN, но операция INNER JOIN не может быть вложена в операцию LEFT JOIN или RIGHT JOIN.  Более подробные сведения по этому вопросу можно найти в описании операции INNER JOIN.

            Можно связать несколько предложений ON.  Более подробные сведения по этому вопросу можно найти в описании операции INNER JOIN.

 

2.7.4.Соединение отношения с самим собой.

Выдать все пары поставщиков, такие, что образующие их поставщики

сораз­ме­щены.

 

SELECT first.NP, second.NP

FROM S first, S second

WHERE first.CITY=second.CITY

AND first.np<second.np

 

Для того,  чтобы различать вхождения таблицы S,  для нее вводятся  псевдо­ни­мы  first, second.

Отметим, что аналогично могут быть назначены псевдонимы  столбцам:

 

SELECT first.np np1, second.np np2

FROM s first, s second

WHERE first.city=second.city

AND np1<np2;

(Ни GUPTA ни Microsoft Dbase-iV - драйвер с этим не согласились.)

 

2.7.5.    Вложенные запросы.

Запросы могут быть вложенными, например:

 

SELECT FAM FROM S WHERE NP IN

(SELECT NP FROM SP WHERE ND="P2")

 

Число уровней вложенности произвольно.

ПРИМЕР: Выдать  фамилии  поставщиков,  которые  поставляют по

край­ней  мере одну красную деталь.

 

SELECT fam FROM s WHERE np IN

    (SELECT np FROM sp WHERE nd IN

        (SELECT nd FROM p WHERE color='красный')

    );

 

2.7.6.    Количественный предикат

Количественный предикат имеет вид:

 

<выражение> <оператор сравнения> (ANY ¦ ALL) <подзапрос>

 

Подзапрос может возвратить только один столбец, но любое число строк.

Если  ука­зано ALL, то предикат является истинным, если результирующее мно­жество пусто или сравнение является истинным для всех элементов мно­­­­­же­ства. Для ANY результат истина, если сравнение является истинным по крайней ме­ре для одного значения в ре­зуль­тирующем множестве; если множество пусто, то результат - ложь.

 

2.7.7.    Коррелированный подзапрос

Выдать фамилии  поставщиков,  которые  поставляют  деталь P2.

Рас­смотрим такое решение:

 

SELECT fam FROM s WHERE 'P2' IN

(SELECT nd FROM sp WHERE np=s.np);

 

В последней строке неуточненная ссылка на np уточняется неявным обра­­зом име­нем таблицы sp.  Здесь внутренний запрос не  может быть об­ра­­ботан полностью до на­чала обработки внешнего, поскольку он зависит от пе­ременной s.np, которая изме­ня­ет­ся по мере прохождения по кортежам s. Та­кой  запрос называют коррелированным.

2.7.8.    Использование одной и той же таблицы в подзапросе и внешнем запросе.

 

Выдать номера поставщиков, которые поставляют по крайней мере одну

деталь, поставляемую поставщиком S2.

 

SELECT DISTINCT np FROM sp WHERE nd IN

    (SELECT nd FROM sp WHERE np='S2');

 

Здесь ссылка на sp в подзапросе и в запросе  означают  разные переме­н­ные. Эквивалентный запрос с использованием соединения имеет вид:

 

SELECT DISTINCT spx.np FROM sp spx, sp spy WHERE

 spx.nd=spy.nd AND spy.np='S2';

 

2.7.9.    Одна и та же таблица в коррелированном и внешнем запросе

 

    Выдать номера деталей, поставляемых более чем одним поставщиком.

 

SELECT DISTINCT spx.nd FROM sp spx WHERE spx.nd IN

  (SELECT spy.nd FROM sp spy WHERE spy.np!=spx.np);

 

Иногда пользователь может знать, что запрос должен возвратить ровно од­но зна­че­ние.  Например: выдать номера поставщиков, находящихся в том же  го­роде, что и пос­тавщик S1.

SELECT np FROM s WHERE city=(SELECT city FROM s WHERE np='S1');

Однако, если подзапрос возвращает более 1 значения,  то будет возникать

ошиб­ка.  Ошибка не возникнет, если подзапрос ничего не возвратит.  Это все рав­но,  как если бы было возвращено неопределенное значение.

 

2.7.10.Квантор существования.

    Запрос: фамилии поставщиков, которые поставляют деталь P2.

 

    SELECT FAM FROM S

    WHERE Exists

        (SELECT * FROM SP

         WHERE NP=S.NP AND ND="P2")

 

Значение Exists(SELECT  FROM...)=<истина>,  если  (SELECT...)

не пусто. (Можно использовать NOT EXISTS).

    Запрос: выдать фамилии поставщиков,  поставляющих все детали.

 

SELECT fam FROM s WHERE NOT EXISTS

  (SELECT * FROM p WHERE NOT EXISTS

    (SELECT * FROM sp WHERE np=s.np AND nd=p.nd));

 

Фактически исходная формулировка перефразирована  к:  Не  существует

дета­ли  такой,  что не существует записи в sp,  указывающей, что данный

пос­тав­щик пос­тав­ля­ет эту деталь.”

 

2.7.11. Квантор общности.

Квантор общности (Forall) в SQL не поддерживается,  но  легко

вос­­про­­и­зво­­дится по известным правилам:

 

Forall x(p)=NOT (Exists x (NOT (p)))

 

Пример: выдать номера поставщиков,  которые  поставляют  все, что

пос­тавляет  S2.

 

SELECT DISTINCT NP FROM SP SPX

    WHERE NOT Exists

        (SELECT * FROM SP SPY

         WHERE NP='S2' AND NOT Exists

             (SELECT * FROM SP SPZ

              WHERE SPZ.NP=SPX.NP AND SPZ.ND=SPY.ND));

 

2.7.12.Запрос с импликацией

Импликация <если p то q> не поддерживается в  SQL  непосредственно.

Ее мож­но вы­ра­зить как <!p ¦¦ q>.

Запрос : "Выдать всех поставщиков,  поставляющих все те детали, которые

по­с­тав­ля­ет 'S2'".

Пусть утверждение p="Поставщик S2 поставляет деталь Py"; Утверждение q="Поставшик Sx поставляет деталь Py". Тогда предикат !p ¦¦ q в SQL будет записан:

 

NOT EXISTS

  (SELECT * FROM sp spy WHERE spy.np='S2')

OR EXISTS

  (SELECT * FROM sp spz WHERE spz.np=Sx

    AND spz.nd=spy.nd)

 

Следовательно, предикат FORALL Py (NOT p ¦¦ q) может быть записан в

виде:

NOT EXISTS Py(NOT(NOT p OR q) или NOT EXISTS Py (p AND NOT q) и полный запрос выглядит также, как в предыдущем примере.

 

2.7.13.Стандартные функции.

    Count, Sum, Avg, Max, Min

 

    Примеры:

    SELECT Count(*) FROM S;

 

    SELECT Count(DISTINCT NP) FROM SP;

 

    SELECT Count(*) FROM SP WHERE ND="P2";

 

    SELECT Sum(AMOUNT) FROM SP WHERE...

 

    SELECT NP,STATUS,CITY FROM S SX

    WHERE STATUS >=

       (SELECT Avg(STATUS) FROM S SY

        WHERE SY.CITY=SX.CITY);

 

2.7.14.Фраза GROUP BY

Имеет смысл близкий к Total в Clipper.

Пример:

    SELECT ND,Sum(AMOUNT) FROM SP GROUP BY ND

Приведенный пример  вычисляет общий объем поставок для каждой

де­та­ли.

Пример 2:

Выдать для каждой детали ее номер и общий объем поставок, за

исклю­

чением  поставщика S1.

 

SELECT nd, sum(amount) FROM sp WHERE NOT np='s1' GROUP BY nd;

 

Строки, не удовлетворяющие фразе WHERE исключаются до того, как будет вы­пол­нено группирование.

 

2.7.15.Фраза HAVING

Фраза HAVING для групп играет такую же роль, как WHERE для строк.

Пример:

выдать номера деталей, поставляемых более, чем одним поставщиком.

 

SELECT nd FROM sp GROUP BY nd HAVING count(*)>1;

 

Если WHERE исключает строки из исходной таблицы, то HAVING - из резуль­тата. Конструкция HAVING работает на одном уровне. Невозможно разбить каждую груп­пу на подгруппы и применить к ним некоторую стандартную функцию. Приведенный  запрос можно сделать без GROUP BY и без HAVING:

 

SELECT DISTINCT nd FROM sp spx WHERE 1<

  (SELECT COUNT(*) FROM sp spy WHERE spy.nd=spx.nd);

 

Такая реализация более очевидна.

 

2.7.16.UNION

 

UNION -  это  теоретико-множественная  операция  объединения. Напри­мер: выдать номера деталей,  которые имеют WEIGHT >  16  или постав­ляются поставщиком S2.

 

    SELECT ND FROM P WHERE WEIGHT>16

        UNION

    SELECT ND FROM SP WHERE NP="S2";

 

Состав и описания  полей  двух  объединяемых таблиц  должны  быть пол­ностью оди­­­­наковы. UNION может объединять любое число SELECT. Дубли­каты исклю­ча­ются из результата.

Пересечение и разность непосредственно не  поддерживаются, но модели­ру­ются с помощью Exists.

Пусть A - поставщики из Лондона

                 B - поставщики, поставляющие деталь S2

Тогда пересечение A и B:

 

    SELECT NP FROM A WHERE Exists

        (SELECT NP FROM B WHERE B.NP=A.NP);

 

Разность A-B  можно  получить,  если  заменить  Exists на NOT Exists.

 

2.7.17.Операции обновления.

2.7.17.1.Оператор UPDATE

 

Оператор UPDATE имеет формат:

                       

    UPDATE <таблица>  SET <поле>=<выражение> [,<поле>=<выражение>]...

    [WHERE <предикат>]

 

Пример 1: (обновление единственной записи.)

Изменить цвет детали P2 на желтый, увеличить ее вес на 5 и установить неопре­де­ленное значение города.

 

UPDATE P SET

  color='желтый',

  weight=weight+5,

  city=NULL

WHERE nd='P2'

 

Пример 2:

Удвоить состояние всех поставщиков, находящихся в Лондоне.

 

UPDATE s SET status=2*status WHERE city='Лондон';

 

Пример 3:

Установить объем поставок равный 0 для всех поставщиков из Лондона.

 

UPDATE sp SET amount=0 WHERE 'Лондон'=

  (SELECT city FROM s WHERE s.np=sp.np);

 

            Невозможно обновить более одной таблицы в одном запросе. Таким обра­зом,  мы сталкиваемся с проблемой ссылочной целостности. Если требуется из­ме­нить  номер  пос­тавщика с s2 на s9 во всей БД, то это можно  сделать двумя операторами SQL:

 

 UPDATE s SET np='s9' where np='s2';

 UPDATE sp SET np='s9' where np='s2';

 

После первого UPDATE БД противоречива. Должны быть или оба опера­тора выполнены, либо ни один из них.

 

2.7.17.2.DELETE

 

    Удаление записей из таблицы выполняется оператором DELETE.

 

    DELETE

    FROM <таблица>

    WHERE <предикат>

2.7.17.3.INSERT

 

    Возможны два формата для оператора, добавляющего записи.

    1) INSERT

       INTO <таблица> [(поле[,поле]...)]

       VALUES (константа[,константа]...)

 

    2) INSERT

       INTO <таблица> [(поле[,поле]...)]

       подзапрос

 

В первом случае в таблицу вставляется строка,  имеющая заданные значения для указанных полей,  причем i-я константа соответствует i-му полю.  Во втором слу­чае ко­пия подзапроса вставляется в таблицу. В обоих случаях  отсутствие  спис­ка  полей  эк­ви­валентно спецификации всех полей.

 

Пример 1. Вставка единственной записи.

INSERT INTO p(np,city,weight) VALUES ('p7,'Москва',2);

 

Отсутствие списка полей эквивалентно спецификации всех полей.

 

Для оператора INSERT также  возможно  создание  противоречий. СУБД не про­ве­ряет существование детали p7.

 

Пример 2. Вставка множества записей.

Для каждой поставляемой детали получить ее номер и общий объем поставок,  сох­ранить результат в БД.

 

CREATE TABLE tmp(nd char(6), volume INTEGER);

INSERT INTO TMP(nd,volume)

  SELECT nd,sum(amount) FROM sp GROUP BY nd;

2.7.17.4.Заключение

 

С операциями  обновления связаны две проблемы.  Первая - ссылочная целост­ность уже упоминалась.

Вторая состоит в том, что существует некоторое ограничение на операции обнов­ления. Если фраза WHERE в UPDATE или DELETE включает подзапрос, то во фразе FROM этого подзапроса не должна упоминаться целевая таблица это­го UP­DATE или  DELETE.  Например,  если нужно удалить всех поставщиков,  сос­тояние которых ниже среднего, то следующий запрос не будет работать.

 

DELETE FROM s WHERE status <

  (SELECT avg(status) from s);

 

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



Популярные новости

Статистика сайта



Rambler's Top100



 
Copyright © НеОфициальный сайт факультета ЭиП