Как выполнить SQL-запрос «SELECT SUM (item.cost * item.amount) ...» - PullRequest
0 голосов
/ 21 апреля 2019

я пытаюсь написать эквивалент 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

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

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 }

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

Ответы [ 2 ]

0 голосов
/ 21 апреля 2019

Вы можете использовать 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] }
0 голосов
/ 21 апреля 2019

Я не нашел, как мы можем использовать times как 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
...