Поделиться через


Практическое руководство. Создание запросов с использованием других источников, помимо таблиц

Обновлен: Ноябрь 2007

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

Использование представления вместо таблицы

Допускается выбор строк из представления. Например, предположим, что в базе данных имеется представление "ExpensiveBooks", каждая строка которого описывает издание стоимостью свыше 19,99. Определение представления может выглядеть следующим образом:

SELECT *
FROM titles
WHERE price > 19.99

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

SELECT *
FROM ExpensiveBooks
WHERE type = 'psychology'

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

SELECT *
FROM sales 
         INNER JOIN 
         ExpensiveBooks 
         ON sales.title_id 
         =  ExpensiveBooks.title_id

Дополнительные сведения о добавлении представления в запрос см. в разделе Практическое руководство. Добавление таблиц в запросы.

Использование запроса вместо таблицы

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

SELECT 
     titles.title_id, title, type
FROM 
     titleauthor 
         INNER JOIN
         titles 
         ON titleauthor.title_id 
         =  titles.title_id 
GROUP BY 
     titles.title_id, title, type
HAVING COUNT(*) > 1

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

SELECT 
    title
FROM 
    (
    SELECT 
        titles.title_id, 
        title, 
        type
    FROM 
        titleauthor 
            INNER JOIN
            titles 
            ON titleauthor.title_id 
            =  titles.title_id 
    GROUP BY 
        titles.title_id, 
        title, 
        type
    HAVING COUNT(*) > 1
    ) 
    co_authored_books
WHERE     type = 'psychology'

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

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

SELECT 
    ExpensiveBooks.title
FROM 
    ExpensiveBooks 
        INNER JOIN
        (
        SELECT 
            titles.title_id, 
            title, 
            type
        FROM 
            titleauthor 
                INNER JOIN
                titles 
                ON titleauthor.title_id 
                =  titles.title_id 
        GROUP BY 
            titles.title_id, 
            title, 
            type
        HAVING COUNT(*) > 1
        )

Дополнительные сведения о добавлении запроса в запрос см. в разделе Практическое руководство. Добавление таблиц в запросы.

Использование определяемых пользователем функций вместо таблицы

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

Например, предположим, что в таблице сотрудников имеется дополнительный столбец employee.manager_emp_id, связанный внешним ключом со столбцом employee.emp_id. В каждой строке таблицы сотрудников столбец manager_emp_id указывает начальника данного сотрудника. Точнее, он указывает на идентификатор emp_id начальника сотрудника. Можно создать пользовательскую функцию, возвращающую таблицу, каждая строка которой представляет сотрудника, входящего в организационную иерархию подчинения для конкретного руководителя. Функцию можно назвать fn_GetWholeTeam и определить так, чтобы входной переменной был идентификатор руководителя, сведения о подчиненных которого требуется извлечь.

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

SELECT * 
FROM 
     fn_GetWholeTeam ('VPA30890F')

"VPA30890F" представляет код emp_id руководителя, сведения о подчиненных которого требуется извлечь. Дополнительные сведения о добавлении определяемой пользователем функции в запрос см. в разделах Практическое руководство. Включение пользовательских функций в запросы и Практическое руководство. Добавление таблиц в запросы. Полное описание пользовательских функций см. в документации SQL Server.

См. также

Другие ресурсы

Работа с хранимыми процедурами и пользовательскими функциями