Как выполнить SQL «ВЫБЕРИТЕ СУММУ (item.cost * item.amount)… » запрос

#kotlin #kotlin-exposed

#kotlin #kotlin-открытый

Вопрос:

я пытаюсь написать эквивалент SQL-запроса:

 SELECT tax.name as tax, SUM(item.cost * item.amount) as total FROM Invoices inv
JOIN InvoiceItems item ON( item.invoice = inv.id )
JOIN Taxes tax ON( tax.id = it.tax )
WHERE inv.id = 1
GROUP BY tax.id
  

Я не могу понять, как «добавить» столбец total в запрос, мой код выглядит следующим образом

 val res = Invoices
            .innerJoin(InvoiceItems, { Invoices.id }, { InvoiceItems.invoice })
            .innerJoin(Taxes, { InvoiceItems.tax }, { Taxes.id })
            .slice( Taxes.name.alias("tax"), InvoiceItems.cost, InvoiceItems.amount )
            .select { Invoices.id eq 1 }
  

Возможно ли вообще сделать это таким образом или я должен сделать это позже в коде?

Ответ №1:

Вы можете использовать TimesOp внутри Expression.build{} блока, например:

     val total = Expression.build { Invoices.cost * Invoices.amount }
    val taxAndTotal = Invoices.innerJoin(InvoiceTaxes).innerJoin(Taxes)
        .slice(Taxes.name, total)
        .select{ Invoices.id eq 1 }
        .groupBy(Taxes.id)
        .map { it[Taxes.name] to it[total] }
  

Ответ №2:

Я не нашел, как мы можем использовать times like InvoiceItems.cost times InvoiceItems.amount , но вы можете создать свой собственный TimesOp объект следующим образом:

 val taxAlias = Taxes.alias("tax")
val itemAlias = InvoiceItems.alias("item")
val invoiceAlias = Invoices.alias("inv")
println(invoiceAlias
        .innerJoin(itemAlias, { invoiceAlias[Invoices.id] }, { itemAlias[InvoiceItems.invoice] })
        .innerJoin(taxAlias, { itemAlias[InvoiceItems.tax] }, { taxAlias[Taxes.id] })
        .slice(
                taxAlias[Taxes.name].alias("tax"),
                TimesOp(
                        itemAlias[InvoiceItems.cost],
                        itemAlias[InvoiceItems.amount],
                        InvoiceItems.amount.columnType
                ).sum().alias("total"))
        .select { invoiceAlias[Invoices.id] eq 1 }
        .groupBy(taxAlias[Taxes.id])
        .prepareSQL(QueryBuilder(false))
)
  

Выводит следующий синтаксис sql для h2:

 SELECT TAX.NAME tax, SUM((ITEM.COST) * (ITEM.AMOUNT)) total FROM INVOICES inv
INNER JOIN INVOICEITEMS item ON INV.ID = ITEM.INVOICE 
INNER JOIN TAXES tax ON ITEM.TAX_ID = TAX.ID 
WHERE INV.ID = 1 
GROUP BY TAX.ID