How to perform SQL "SELECT SUM(item.cost * item.amount)... " query - kotlin

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?

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] }

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

Related

Is it possible in PostgreSQL to do one query to get the result of object inside object?

At this moment I do query like this :
static async getAllAppointmentSerivce () {
// Get all appointment with detail
const query = {
name: 'getAllAppointment',
text: 'SELECT app.id, cus.name as name, cus.email as email, app.date, app.status, app.link FROM appointments app INNER JOIN admins adm ON app.admin_id = adm.id INNER JOIN customers cus ON app.customer_id = cus.id ORDER BY id ASC'
}
return pool.query(query)
.then(async res => {
for (let i = 0; i < res.rows.length; i++) {
const admin = await AdminService.getAdminDetailByAppointmentId(res.rows[i].id)
res.rows[i].admin = admin
}
return res.rows
})
.catch(err => console.log(err.stack))
}
And the result is like this :
Query result
My question is, is that possible to do that in a single query?

SQL Query IF Statment

Im trying to add a if else type function in the below sql query
SELECT OEEL.invoicedt, UCASE(OEEL.whse) AS Whse, OEEL.orderno, OEEL.ordersuf, OEEL.custno, UCASE(OEEL.shipto) AS Shipto, UCASE(OEEL.slsrepin) AS Slsrepin,
UCASE(OEEL.slsrepout) AS Slsrepout, OEEL.returnfl, OEEL.netamt, OEEL.wodiscamt, OEEL.discamtoth, OEEL.qtyship, OEEL.commcost, ICSS.csunperstk, UCASE(ICSD.name) AS Name,
UCASE(ICSD.region) AS Region, UCASE(OEEL.prodcat) AS Prodcat, UCASE(SASTA.descrip) AS Descrip, UCASE(OEEL.transtype) AS Transtype, UCASE(ARSS.user2) AS User2,
OEEL.transdt, ICSS.transdt AS "ICSS.Transdt", ICSD.transdt AS "ICSD.Transdt", SASTA.transdt AS "SASTA.Transdt", ARSS.transdt AS "ARSS.Transdt", { fn CURDATE() } AS CURDATE1, { fn CURTIME() } AS CURTIME2,
OEEL.lineno
FROM { oj { oj { oj { oj PUB.oeel OEEL LEFT OUTER JOIN
PUB.icss ICSS ON OEEL.cono = ICSS.cono AND OEEL.shipprod = ICSS.prod AND OEEL.icspecrecno = ICSS.icspecrecno } LEFT OUTER JOIN
PUB.icsd ICSD ON OEEL.cono = ICSD.cono AND OEEL.whse = ICSD.whse } LEFT OUTER JOIN
PUB.sasta SASTA ON OEEL.cono = SASTA.cono AND OEEL.prodcat = SASTA.codeval } LEFT OUTER JOIN
PUB.arss ARSS ON OEEL.cono = ARSS.cono AND OEEL.custno = ARSS.custno AND OEEL.shipto = ARSS.shipto }
WHERE (OEEL.cono = 1) AND (OEEL.invoicedt BETWEEN { d '2014-06-02' } AND { d '2014-06-03' }) AND (SASTA.codeiden IN ('C', 'c'))
ORDER By OEEL.custno, OEEL.shipto, OEEL.prodcat
i would the if to be something like
if OEEL.returnfl = False THEN (OEEL.netamt-OEEL.wodiscamt-OEEL.discamtoth) AS "SALES"
Else (-1*(OEEL.netamt-OEEL.wodiscamt-OEEL.discamtoth)) AS "SALES"
You can add CASE Statement in your query
CASE WHEN OEEL.returnfl = 'False' THEN (OEEL.netamt-OEEL.wodiscamt-OEEL.discamtoth) ELSE (-1*(OEEL.netamt-OEEL.wodiscamt-OEEL.discamtoth)) END AS "SALES"

SQL subtract alias and create another

i would like to subtract the "alias" i created called "SALES" & "GP" and create a new column call GP
SELECT OEEL.invoicedt, UCASE(OEEL.whse) AS Whse, OEEL.orderno, OEEL.ordersuf,
OEEL.custno, UCASE(OEEL.shipto) AS Shipto, UCASE(OEEL.slsrepin) AS Slsrepin,
UCASE(OEEL.slsrepout) AS Slsrepout, OEEL.returnfl, OEEL.netamt, OEEL.wodiscamt,
OEEL.discamtoth, OEEL.qtyship, OEEL.commcost, ICSS.csunperstk,
UCASE(ICSD.name) AS Name, UCASE(ICSD.region) AS Region,
UCASE(OEEL.prodcat) AS Prodcat, UCASE(SASTA.descrip) AS Descrip,
UCASE(OEEL.transtype) AS Transtype, UCASE(ARSS.user2) AS User2,
OEEL.transdt, ICSS.transdt AS "ICSS.Transdt", ICSD.transdt AS "ICSD.Transdt",
SASTA.transdt AS "SASTA.Transdt", ARSS.transdt AS "ARSS.Transdt",
{ fn CURDATE() } AS CURDATE1, { fn CURTIME() } AS CURTIME2,
OEEL.lineno,
CASE
WHEN OEEL.returnfl = '0' THEN (OEEL.netamt-OEEL.wodiscamt-OEEL.discamtoth)
ELSE (-1*(OEEL.netamt-OEEL.wodiscamt-OEEL.discamtoth))
END AS "SALES",
CASE
WHEN OEEL.returnfl = '0' THEN (OEEL.qtyship*OEEL.commcost*NVL(ICSS.csunperstk,1))
ELSE (-1*OEEL.qtyship*OEEL.commcost*NVL(ICSS.csunperstk,1))
END AS "COST"
FROM { oj
{ oj
{ oj
{ oj PUB.oeel OEEL
LEFT OUTER JOIN PUB.icss ICSS
ON OEEL.cono = ICSS.cono
AND OEEL.shipprod = ICSS.prod
AND OEEL.icspecrecno = ICSS.icspecrecno
}
LEFT OUTER JOIN PUB.icsd ICSD
ON OEEL.cono = ICSD.cono AND OEEL.whse = ICSD.whse
}
LEFT OUTER JOIN PUB.sasta SASTA
ON OEEL.cono = SASTA.cono AND OEEL.prodcat = SASTA.codeval
}
LEFT OUTER JOIN PUB.arss ARSS
ON OEEL.cono = ARSS.cono
AND OEEL.custno = ARSS.custno
AND OEEL.shipto = ARSS.shipto
}
WHERE (OEEL.cono = 1)
AND (OEEL.invoicedt BETWEEN { d '2014-06-02' } AND { d '2014-06-03' })
AND (SASTA.codeiden IN ('C', 'c'))
ORDER BY OEEL.custno, OEEL.shipto, OEEL.prodcat
Add the following at last column
(CASE WHEN OEEL.returnfl = '0' THEN (OEEL.netamt-OEEL.wodiscamt-OEEL.discamtoth) ELSE (-1*(OEEL.netamt-OEEL.wodiscamt-OEEL.discamtoth)) END) - (CASE WHEN OEEL.returnfl = '0' THEN (OEEL.qtyship*OEEL.commcost*NVL(ICSS.csunperstk,1)) ELSE (-1*OEEL.qtyship*OEEL.commcost*NVL(ICSS.csunperstk,1)) END) AS GP

translating sql statement to linq

I have a working sql statement and want it as linq statement or linq methode chain.
My statement is:
SELECT T1.*
FROM (SELECT Col1, MAX(InsertDate) as Data
FROM Zugbewegungsdaten
GROUP BY Loknummer) as temp JOIN T1
ON (T1.Col1= temp.Col1
AND Zugbewegungsdaten.InsertDate= temp.Date)
WHERE Col3=1
ORDER BY Loknummer
Can anybody help me to translate it?
Edit after comment:
Ok, my result for the inner select:
var maxResult = (from data in context.T1
group data by data.Col1
into groups
select new
{
Train = groups.Key,
InsertDate= groups.Max( arg => arg.InsertDate)
}) ;
I tried the join like this:
var joinedResult = from data in context.T1
join gdata in maxResult on new
{
data.Col1,
data.InsertDate
}
equals new
{
gdata.Col1,
gdata.InsertDate
}
select data;
But i get a compiler error by the join that the typeargument are invalid.
In the case that the join works i whould use a where to filter the joinedResult.
var result = from data in joinedResult
where data.Col3 == true
select data;
After much more "try and error", I got this version it looks like it works.
var joinedResult = ( ( from data in context.T1
group data by data.Col1
into g
select new
{
Key= g.Key,
Date = g.Max( p => p.InsertDate)
} ) ).Join( context.T1,
temp => new
{
Key = temp.Key,
InsertDate = temp.Date
},
data => new
{
Key = data.Col1,
InsertDate = data.InsertDate
},
( temp,
data ) => new
{
temp,
data
} )
.Where( arg => arg.data.Col3)
.OrderBy( arg => arg.data.Col1)
.Select( arg => arg.data );
Could it be that i have to set the same property names (Key, InsertDate) by joins over multi columns?

How would i do this SQL in Linq?

SELECT Sum(dbo.amzOrdersItem.price) as SubTotal,
Sum(dbo.amzOrdersItem.shippingPrice) as ShippingTotal,
Sum(dbo.amzOrdersItem.price) + Sum(dbo.amzOrdersItem.shippingPrice) as OrderTotal
FROM dbo.amzOrders INNER JOIN
dbo.amzOrdersItem ON dbo.amzOrders.amzOrderId = dbo.amzOrdersItem.amzOrderId
WHERE dbo.amzOrders.id = '14818'
GROUP BY dbo.amzOrders.id
The query would look like this:
var query =
from order in db.amzOrders
join item in db.amzOrdersItems on order.amzOrderId equals item.amzOrderId
where order.Id == 14818
group item by order.Id into g
select new
{
SubTotal = g.Sum(i => i.Price),
ShippingTotal = g.Sum(i => i.ShippingPrice),
OrderTotal = g.Sum(i => i.Price) + g.Sum(i => i.ShippingPrice),
};
I'm not sure if the L2SQL query provider would be able to translate the OrderTotal line correctly for sure, hopefully it is simple enough.
maybe this (but its untested):
var result = from order in Context.amzOrders
where order.id == '14818'
from orderItems in Context.amzOrdersItem
on order.amzOrderId equals orderItems.amzOrderId
into orderItemsJoinData
let subTotal = orderItemsJoinData.Sum( item => item.price )
let shippingTotal = orderItemsJoinData.Sum( item => item.shippingPrice )
select new
{
SubTotal = subTotal ,
ShippingTotal = shippingTotal,
OrderTotal = subTotal + shippingTotal
};