Однако оператор SELECT также может возвращать атрибуты. Если у Customer имеется firstName, то SELECT c.firstName возвратит строку или коллекцию строк с firstName.
Чтобы извлечь firstName и lastName сущности Customer, вам потребуется сгенерировать список, который будет включать два следующих атрибута:
SELECT c.firstName, c.lastName
FROM Customer c
С выходом версии JPA 2.0 появилась возможность извлекать атрибуты в зависимости от условий (с использованием выражения CASE WHEN… THEN… ELSE… END). Например, вместо извлечения значения, говорящего о цене книги, оператор может возвратить расчет цены (например, с 50 %-ной скидкой) в зависимости от издателя (например, с 50 %-ной скидкой на книги от «Apress» и 20 %-ной скидкой на все прочие книги).
SELECT CASE b.editor WHEN 'Apress'
·····················THEN b.price * 0.5
·····················ELSE b.price * 0.8
·······END
FROM Book b
Если сущность Customer связана отношением «один к одному» с Address, то c.address будет ссылаться на адрес клиента, а в результате выполнения приведенного далее запроса будет возвращен не список клиентов, а список адресов:
SELECT c.address
FROM Customer c
Навигационные выражения можно объединять в цепочку для обхода комплексных EntityGraph. Благодаря этой методике можно создавать выражения путей, например c.address.country.code, ссылающиеся на код страны в адресе клиента:
SELECT c.address.country.code
FROM Customer c
В выражении SELECT можно применять конструктор для возврата экземпляра Java-класса, который инициализируется с использованием результата запроса. Класс не обязан быть сущностью, однако конструктор должен быть полностью уточненным и сочетаться с атрибутами.
SELECT NEW org.agoncal.javaee7.CustomerDTO(c.firstName, c.lastName, c.address.street1)
FROM Customer c
Результатом этого запроса будет список объектов CustomerDTO, экземпляры которых были созданы с применением оператора new и инициализированы с использованием имен, фамилий и улиц проживания клиентов.
Выполнение показанных далее запросов приведет к возврату одного значения или коллекции, в которую будет входить нуль и более сущностей (или атрибутов), включая дубликаты. Для удаления дубликатов необходимо воспользоваться оператором DISTINCT.
SELECT DISTINCT c
FROM Customer c
SELECT DISTINCT c.firstName
FROM Customer c
Результатом запроса может оказаться результат выполнения агрегатной функции, примененной в выражении пути. В операторе SELECT могут быть использованы следующие агрегатные функции: AVG, COUNT, MAX, MIN, SUM. Результаты можно сгруппировать оператором GROUP BY и профильтровать оператором HAVING.
SELECT COUNT(c)
FROM Customer c
Скалярные выражения тоже могут быть использованы в операторе SELECT запроса, равно как и в операторах WHERE и HAVING. Эти выражения можно применять в отношении числовых (ABS, SQRT, MOD, SIZE, INDEX) и строковых значений (CONCAT, SUBSTRING, TRIM, LOWER, UPPER, LENGTH, LOCATE), а также значений даты/времени (CURRENT_DATE, CURRENT_TIME, CURRENT_TIMESTAMP).
FROM
Оператор FROM определяет сущности путем объявления идентификационных переменных.
SELECT c
FROM Customer c
WHERE
Оператор WHERE состоит из условного выражения, используемого для ограничения результатов выполнения оператора SELECT, UPDATE или DELETE. Оператор WHERE может быть простым выражением либо набором условных выражений, применяемых для фильтрации результатов запроса.
Самый простой способ ограничить результаты запроса — использовать атрибут сущности. Например, приведенный далее запрос обеспечивает выборку всех клиентов, для которых firstName имеет значение Винсент:
SELECT c
FROM Customer c
WHERE c.firstName = 'Винсент'
Вы можете еще больше ограничить результаты запросов, используя логические операторы AND и OR. В приведенном далее примере AND задействуется для выборки всех клиентов, для которых firstName имеет значение Винсент, а country — значение Франция:
SELECT c
FROM Customer c
WHERE c.firstName = 'Винсент' AND c.address.country = 'Франция'