im trying to write equivalent of SQL query:

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

I can't figure out how to "add" total column to the query, my code is as follows

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 }

Is it even possible to do it this way or i have to do it later in code?

2 Answers

0
Tapac On Best Solutions

You can use TimesOp within Expression.build{} block, like this:

    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
awesoon On

I did not find how can we use times like InvoiceItems.cost times InvoiceItems.amount, but you can construct your own TimesOp object like this:

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

Outputs the following sql for h2 syntax:

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