Подзапросы с функцией выбора в CLSQL

Я пытаюсь создать подзапрос с помощью функции clsql:select:

CL-USER> (select [books.bookid] 
         :from [books] 
         :where
           (sql-in [books.bookid]
               (select [bookid] 
                   :from [bookauthors]
                   :where 
                   (sql-= [bookauthors.authorid] 120))))
;; 2015-03-07T06:37:08 /books/ => SELECT BOOKID FROM BOOKAUTHORS WHERE (BOOKAUTHORS.AUTHORID = 120)
;; 2015-03-07T06:37:08 /books/ => SELECT BOOKS.BOOKID FROM BOOKS WHERE (BOOKS.BOOKID IN ((157)))
((157))
("bookid")

Это работает, но вместо генерации одного запроса с предложением sub-select clsql выполняет два запроса. Это не так эффективно, как позволить бэкенду postgresql обрабатывать все это.

CL-USER> (clsql-sys:db-type-has-subqueries? :postgresql)
T

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

1 ответ

Решение

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

Вы должны использовать sql-выражения вместо функций. если ты (clsql-sys:file-enable-sql-reader-syntax) это можно сделать с помощью квадратных скобок следующим образом.

(select [books.bookid] :from [books] :where [in [books.bookid] [select [bookid] :from [bookauthors] :where [= [bookauthors.authorid] 120]]))


Кроме того, вы можете использовать :postgresql-socket3 бэкэнд, поскольку он является самым надежным / самым последним из трех бэкэндов postgresql clsql (он использует cl-postgresql библиотека предоставлена postmodern чтобы получить доступ к postgresql через версию 3 его сокета API. :posgresql-socket использует версию 2 сокета postgres api, и :postgres использует FFI через клиент C

Другие вопросы по тегам