Knex.js Select Average and Round - mysql

I am switching an application from PHP/MYSQL to Express and am using knex to connect to the MYSQL database. In one of my queries I use a statement like such (I have shortened it for brevity.)
SELECT ROUND(AVG(Q1),2) AS Q1 FROM reviews WHERE id=? AND active='1'
I am able to use ROUND if I use knex.raw but I am wondering if there is a way to write this using query builder. Using query builder makes dealing with the output on the view side so much easier than trying to navigate the objects returned from the raw query.
Here is what I have so far in knex.
let id = req.params.id;
knex('reviews')
//Can you wrap a ROUND around the average? Or do a Round at all?
.avg('Q1 as Q1')
.where('id', '=', id)
Thanks so much!

You can use raw inside select. In this case:
knex('reviews')
.select(knex.raw('ROUND(AVG(Q1),2) AS Q1'))
Check the docs here for more examples and good practices when dealing with raw statements.

Related

Select a sum in Knex.js without using .raw

I am trying to rewrite some MySQL queries in Knex.js, and I feel like I'm running into .raw at every turn, which feels counter to the reason I want to use Knex in the first place.
Is it possible to write the following query without using .raw?
SELECT
product,
SUM(revenue)
FROM orders
Using raw, it works to write:
knex()
.select(
'product',
knex.raw('SUM(revenue)')
)
.from('orders')
but the idea of using Knex was to avoid using MySQL query strings, so I'm hoping there's another way. Or does everyone just use .raw everywhere, and I'm misunderstanding something? Very possible, I'm new to this.
You can use the sum method.
sum — .sum(column|columns|raw) Retrieve the sum of the values of a
given column or array of columns (note that some drivers do not
support multiple columns). Also accepts raw expressions.
knex('users').sum('products')
Outputs:
select sum("products") from "users"
Probably be something like this:
knex()
.select('product')
.sum('revenue')
.from('orders')
You should adjust to your specific case. You might need to use something like groupBy('product') to get total revenue per product.
You should really go over knex's documentation, it's pretty good and straight forward and you definitely should not be using raw all the time.
You can even specify the returning sum column name like this:
knex(tableName)
.select('product')
.sum({ total: 'revenue' })
.groupBy('product');

Trouble putting together a SoQL query with Socrata

I have this query that I put together in MySQL in my test db and am trying to figure out how to port it over to the SoQL SODA API. Pretty much just trying to get a list of the unique business and associated details.
SELECT DISTINCT
(CAMIS), dba, boro, building, street
FROM
nyc_stuff.restauraunt_inspections
WHERE
BORO = 'BRONX';
This is the base url I'm using:
https://data.cityofnewyork.us/resource/xx67-kt59.json
I'm aware of how to use the clauses, but can't figure out how to add Distinct into the query.
I tired this:
https://data.cityofnewyork.us/resource/xx67-kt59.json?$select=DISTINCT%20(CAMIS)
But no luck...
You can accomplish this by using the $query parameter in SoQL. I would suggest:
https://data.cityofnewyork.us/resource/xx67-kt59.json?$query=SELECT%20distinct%20camis,%20dba,%20boro,%20building,%20street%20WHERE%20boro%20=%20%22BRONX%22
Thanks, Socrata Support

MySQLi PHP using OR and AND

Sorry about the title, I wasn't sure how to word it
I'm wanting to make a instant messaging system with PHP (I've done ajax for it) but I'm not sure how to get the query, I'm wanting something like this:
"SELECT * FROM messages WHERE user='$to' AND sender='$username' OR user='$username' AND sender='$to'"
Does anyone know if this is possible? Or a mysqli_fetch_array for two invididual queries on the same variable.
You can use parenthesis to use multiple operations to work as single operation in query. This is the typical approach anyway, and very useful for using multiple AND, OR operators in a query.
For you case, query should be like
"SELECT * FROM messages WHERE ( user='$to' AND sender='$username' ) OR ( user='$username' AND sender='$to' )"
Notice that tho we used 4 conditions, but with parenthesis we shrieked it into 2 separate conditions and ultimately one OR operation in the query.
Some good reading about this stuff at this article in case you want to dig it more

Rails: ActiveRecord - Custom SQL

What is the best way, using ActiveRecord, to execute the following SQL:
SELECT parent.*
FROM sections AS node, sections AS parent
WHERE node.left BETWEEN parent.left AND parent.right
ORDER BY parent.left DESC
LIMIT 1
I know is possible to use .limit(), .where() and .order() but how do you deal with 'from'?
Or is it better just to execute the whole lot as a single statement?
Thanks for any help.
There's nothing wrong with using SQL in your application so long as you can verify it's working correctly and isn't exposing you to injection attacks. Since this statement is executed as-is you're okay in that regard.
ActiveRecord::Base.connection provides a method for executing arbitrary queries and retrieving the results in a variety of formats. select_all or select_rows may be what you're looking for.
The AREL query generator is not always as clever as we'd like, so when in doubt go with the simplest form of expression. In your case it seems to be that chunk of SQL.
To re-write it using AREL you'd have to use the join method to link it back on itself.
Parent.from('sections AS node, sections AS parent')
.where('node.left BETWEEN parent.left AND parent.right')
.order('parent.left DESC')
.limit(1)
And you get the benefit of chaining.

Subsonic 3.0 Query limit with MySQL c#.net LinQ

a quick question which may or may not be easily answered.
Currently, in order to return a limited result set of data to my calling reference using SubSonic I use a similar function as below:
_DataSet = from CatSet in t2_aspnet_shopping_item_category.All()
join CatProdAssignedLink in t2_aspnet_shopping_link_categoryproduct.All() on CatSet.CategoryID equals CatProdAssignedLink.CategoryID
join ProdSet in t2_aspnet_shopping_item_product.All() on CatProdAssignedLink.ProductID equals ProdSet.ProductID
where ProdSet.ProductID == __ProductID
orderby CatProdAssignedLink.LinkID ascending
select CatSet;
and select the first item from the data set.
Is there a way to limit the lookup initially to a certain amount of rows? I'm using MySQL as the base database.
You can do that using following:
Using SubSonic:
If you want to get limited records from subsonic function then you can use GetPaged method to get records. To learn more about querying visit this link.
Use GetPaged instead of GetAll function in your query.
Using LINQ
Use Skip and Take methods to get limited records. To learn more about linq visit this link.