2015-03-07 13 views
5

Ich bin versucht, eine Unterabfrage mit dem CLSQL zu erstellen: select Funktion:Unterabfragen mit Auswahlfunktion in CLSQL

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") 

Es funktioniert, aber statt eine Abfrage mit einer Unter select-Klausel zu erzeugen, CLSQL läuft zwei Abfragen. Dies wird nicht so effizient sein, wie das Postgresql-Backend das ganze Ding behandeln lässt.

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

Offensichtlich unterstützt der Postgresql-Connector Unterabfragen. Gibt es eine Möglichkeit, die select-Funktion zu generieren?

Antwort

2

In Ihren oben genannten Aufrufen führen Sie tatsächlich die innere Auswahl aus, und spleißen dann die Ergebnisse in den äußeren Anruf.

Sie sollten sql-Ausdrücke anstelle von Funktionen verwenden. Wenn Sie (clsql-sys:file-enable-sql-reader-syntax) können dies mit eckigen Klammern wie folgt erreicht werden.

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


Auch möchten Sie vielleicht die :postgresql-socket3 Backend verwenden, da es die robusteste ist/jüngste der drei postgresql CLSQL Backends (es verwendet die cl-postgresql von postmodern bereitgestellt Bibliothek postgresql zuzugreifen durch Version 3 seiner Socket-API :posgresql-socket verwendet Version 2 des Postgres-Sockets api und :postgres verwendet das FFI über den C-Client

+0

Verwenden Sie (SQL-Abfrage ...) anstelle von [wählen ...] if sql -Reader-Syntax ist nicht aktiviert. – BnMcGn