2013-02-17 33 views
9

मैं चालाक 1.0.0 के साथ इस एसक्यूएल निर्माण करने के लिए कोशिश कर रहा हूँ:कैसे चयन खंड में नेस्टेड प्रश्नों लिखने के लिए

select 
    cat.categoryId, 
    cat.title, 
    (
     select 
     count(product.productId) 
     from 
     products product 
     right join products_categories productCategory on productCategory.productId = product.productId 
     right join categories c on c.categoryId = productCategory.categoryId 
     where 
     c.leftValue >= cat.leftValue and 
     c.rightValue <= cat.rightValue 
    ) as productCount 
from 
    categories cat 
where 
    cat.parentCategoryId = 2; 

मेरे सबसे सफल प्रयास (मैं, "मिलती है" भाग गिरा तो यह अधिक पठनीय है):

def subQuery(c: CategoriesTable.type) = (for { 
     p <- ProductsTable 

     } yield(p.id.count)) 
     for { 
     c <- CategoriesTable 
     if (c.parentId === 2) 
     } yield(c.id, c.title, (subQuery(c).asColumn)) 

जो एसक्यूएल सबक्वेरी में कोष्ठक कमी पैदा करता है: जो स्पष्ट रूप से है अमान्य एसक्यूएल

select 
    x2.categoryId, 
    x2.title, 
    select count(x3.productId) from products x3 
    from 
    categories x2 
    where x2.parentCategoryId = 2 
कोई विचार कैसे स्लिक को सही ढंग से इन कोष्ठक डालता है? या शायद इसे हासिल करने का एक अलग तरीका है?

+1

आप अपने प्रयासों के साथ-साथ पोस्ट कर सकते हैं:

// first create a function to create a count query def countCoffees(supID: Column[Int]) = for { c <- Coffees if (c.supID === supID) } yield (c.length) // create the query to combine name and count val coffeesPerSupplier = for { s <- Suppliers } yield (s.name, countCoffees(s.id) as "test") // print out the name and count coffeesPerSupplier foreach { case (name, count) => println(s"$name has $count type(s) of coffee") } 

परिणाम है? –

+0

मैंने पोस्ट किया है जो मुझे अब तक मिला है – wassertim

+0

यह मुझे क्वेरी कंपाइलर में एक बग/निरीक्षण की तरह दिखता है। शायद आपको एक बग रिपोर्ट दर्ज करनी चाहिए। –

उत्तर

11

मैंने स्लिम या स्कैलाक्वायर का कभी भी उपयोग नहीं किया था, इसलिए यह पता लगाने के लिए काफी रोमांच था कि इसे कैसे प्राप्त किया जाए। Slick बहुत एक्स्टेंसिबल है, लेकिन विस्तार पर प्रलेखन थोड़ा मुश्किल है। यह पहले से मौजूद हो सकता है, लेकिन यह वही है जो मैं आया था। अगर मैंने कुछ गलत किया है, तो कृपया मुझे सही करें।

सबसे पहले हमें कस्टम ड्राइवर बनाने की आवश्यकता है। मैंने आसानी से परीक्षण करने में सक्षम होने के लिए H2Driver बढ़ाया।

trait CustomDriver extends H2Driver { 

    // make sure we create our query builder 
    override def createQueryBuilder(input: QueryBuilderInput): QueryBuilder = 
    new QueryBuilder(input) 

    // extend the H2 query builder 
    class QueryBuilder(input: QueryBuilderInput) extends super.QueryBuilder(input) { 

    // we override the expr method in order to support the 'As' function 
    override def expr(n: Node, skipParens: Boolean = false) = n match { 

     // if we match our function we simply build the appropriate query 
     case CustomDriver.As(column, LiteralNode(name: String)) => 
     b"(" 
     super.expr(column, skipParens) 
     b") as ${name}" 

     // we don't know how to handle this, so let super hanle it 
     case _ => super.expr(n, skipParens) 
    } 
    } 
} 

object CustomDriver extends CustomDriver { 
    // simply define 'As' as a function symbol 
    val As = new FunctionSymbol("As") 

    // we override SimpleSql to add an extra implicit 
    trait SimpleQL extends super.SimpleQL { 

    // This is the part that makes it easy to use on queries. It's an enrichment class. 
    implicit class RichQuery[T: TypeMapper](q: Query[Column[T], T]) { 

     // here we redirect our as call to the As method we defined in our custom driver 
     def as(name: String) = 
     CustomDriver.As.column[T](Node(q.unpackable.value), name) 
    } 
    } 

    // we need to override simple to use our version 
    override val simple: SimpleQL = new SimpleQL {} 
} 

आदेश में इसका इस्तेमाल करने की हम विशिष्ट बातें आयात करने की आवश्यकता: फिर

import CustomDriver.simple._ 
import Database.threadLocalSession 

, इसका इस्तेमाल करने के लिए आप निम्न (मैं अपने उदाहरण में आधिकारिक स्लिक प्रलेखन से टेबल प्रयुक्त) कर सकते हैं ।

Acme, Inc. has 2 type(s) of coffee 
Superior Coffee has 2 type(s) of coffee 
The High Ground has 1 type(s) of coffee 
+0

यह अब अच्छा काम करता है। आपका बहुत बहुत धन्यवाद! – wassertim