MySQL Query works in phpmyadmin but not in node - mysql

I have a query with LEFT joins which works fine in phpmyadmin but same query returns null for certain rows in node server. I am new to both node and MySQL.
Here is my query to fetch highest selling category between a date range:
SELECT o.order_id,c.category_id,c.category_name as Name, o.book_id, o.date_of_purchase, SUM(o.quantity) as Total, o.payment_method
FROM `order_details` as o
LEFT JOIN book as b on b.book_id = o.book_id
LEFT JOIN category as c on c.category_id = b.book_id
GROUP BY c.category_id
ORDER BY Total DESC LIMIT 1
Am i doing something wrong here?
Here are my table and query result:
Result of the same in node is :
{
"data": [
{
"order_id": 20,
"category_id": null,
"Name": null,
"book_id": 6,
"date_of_purchase": "2017-07-23T13:22:37.000Z",
"Total": 55,
"payment_method": "NB"
}
],
"status": 1,
"message": "Success"
}
Node code where I call the query:
/* Get highest selling category */
category.getHighestSelling = function(fromDate, toDate) {
var query = "SELECT min(o.order_id) , c.category_id , c.category_name as Name , o.book_id , min(o.date_of_purchase) , SUM(o.quantity) as Total , min(o.payment_method) " +
"FROM `order_details` as o " +
"LEFT JOIN book as b on b.book_id = o.book_id " +
"LEFT JOIN category as c on c.category_id = b.book_id " +
"GROUP BY c.category_id , o.book_id " +
"ORDER BY Total DESC LIMIT 1 ";
if (fromDate && toDate) {
query += "WHERE `date_of_purchase` BETWEEN '" + dateFormat(fromDate, "yyyy-mm-dd , h:MM:ss ") + "' AND '" + (dateFormat(toDate, "yyyy-mm-dd , h:MM:ss ") || new Date()) + "'";
}
return utilities.executeQuery(query);
};

Related

Mysql error when select like

pls help to solve below mentioned error :
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'r.Username LIKE '%usernameanswer%' and r.Createtime > NOW() - INTERVAL 30 SECOND
Code
public List <CorrekctanswerModel> answerlist(String usernameanswer) throws Exception {
log.info("daomimpl" + usernameanswer);
List<CorrekctanswerModel> answerarray = new ArrayList<CorrekctanswerModel>();
Connection c = null;
PreparedStatement ps = null;
ResultSet rs = null;
String sql = " select s.NAME as Subject, d.value as variant, r.Username, r.UserAnswer, r.Correctanswer, r.Createtime from resultlog r " +
" inner join test_table t on t.ID = r.QuestionId " +
" inner join subject s on s.ID= t.SUBJECT " +
" inner join dictionary d on d.ID = t.Variant" +
"where r.Username LIKE '%usernameanswer%' and r.Createtime > NOW() - INTERVAL 30 SECOND " ;
try {
c = DbHelper.getConnection();
if (c != null) {
ps = c.prepareStatement(sql);
rs = ps.executeQuery();
while (rs.next()) {
CorrekctanswerModel rep = new CorrekctanswerModel();
rep.setSubject(rs.getString("Subject"));
rep.setVariant(rs.getString("variant"));
rep.setUsername(rs.getString("Username"));
rep.setUseranswer(rs.getString("UserAnswer"));
rep.setCorrekctanswer(rs.getString("Correctanswer"));
rep.setCreatedate(rs.getDate("Createtime"));
answerarray.add(rep);
}
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
JdbcUtility.close(c, ps, rs);
}
return answerarray;
}
I'm going to add this as an answer in case someone stumbles upon this question...
In your code, SQL is generated with these lines:
String sql = " select <fields> from resultlog r " +
" inner join test_table t on t.ID = r.QuestionId " +
" inner join subject s on s.ID= t.SUBJECT " +
" inner join dictionary d on d.ID = t.Variant" +
"where r.Username LIKE '%usernameanswer%' and ... " ;
There should be a white space before where OR a white space after t.Variant. In its current form, the query will do this:
... inner join dictionary d on d.ID = t.Variantwhere r.Username ...
Adding a space before where like so:
String sql = " select <fields> from resultlog r " +
" inner join test_table t on t.ID = r.QuestionId " +
" inner join subject s on s.ID= t.SUBJECT " +
" inner join dictionary d on d.ID = t.Variant" +
" where r.Username LIKE '%usernameanswer%' and ... " ;
will result in your query written like this:
... inner join dictionary d on d.ID = t.Variant where r.Username ...
Also, it looks like usernameanswer is a variable. If it is, the where clause will look like this:
" where r.Username LIKE '%" + usernameanswer + "%' and ... " ;

Mysql query doesn't work in qt

I have written a pretty complex mysql query and test it in mysql workbench, it works very well. But when I use this query in my qt program, it doesn't work.
For better resolution I have 3 tables (products, categories, products_categories) and I want to fetch 3 category with parentId = 5 and 2 product of each category. here is my function:
void DbQueries::getFullCategories(int parent_id, int offset, int limit, int plimit)
{
...
QSqlQuery q;
q.prepare("set #num := 0, #cid := '';"
"SELECT e.ProductId, e.title, e.price, e.rate, e.rateAvg, e.imgUrl, d.cid, d.ctitle"
"FROM products e,"
"(SELECT ProductId, #num := if(#cid = categoryId, #num + 1, 1) as qty, #cid := categoryId as cid, title as ctitle"
"FROM ("
"SELECT b.ProductId, b.categoryId, a.title"
"FROM products_categories b, (SELECT catId, title FROM categories WHERE parentId = :parent_id LIMIT :limit OFFSET :offset) as a"
"WHERE b.categoryId = a.catId"
"ORDER BY b.categoryId"
") as c"
") as d"
"WHERE e.ProductId = d.ProductId AND d.qty <= :plimit"
"ORDER BY d.cid;");
q.bindValue(":parent_id", parent_id);
q.bindValue(":limit", limit);
q.bindValue(":offset", offset);
q.bindValue(":plimit", plimit);
if(!q.exec())
qDebug() << q.lastError().text();
const QSqlRecord &r = q.record();
qDebug() << r.count();
...
}
With this query, after exec() I get no error but there is no record fetched in my QSqlRecord. I tried to put \ before := and I got Unknown escape sequence '\:'.
And when I reduced my query to this:
QSqlQuery q;
q.prepare("SELECT b.ProductId, b.categoryId, a.title"
"FROM products_categories b, (SELECT catId, title FROM categories WHERE parentId = :parent_id LIMIT :limit OFFSET :offset) as a"
"WHERE b.categoryId = a.catId"
"ORDER BY b.categoryId");
I got mysql error like: "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'b, (SELECT catId, title FROM categories WHERE parentId = 5 LIMIT 3 OFFSE' at line 1 QMYSQL: Unable to execute query"
This query has some important white space missing:
"SELECT b.ProductId, b.categoryId, a.title"
"FROM products_categories b, (SELECT catId, title FROM categories WHERE parentId = :parent_id LIMIT :limit OFFSET :offset) as a"
"WHERE b.categoryId = a.catId"
"ORDER BY b.categoryId"
Fix is really simple:
"SELECT b.ProductId, b.categoryId, a.title"
" FROM products_categories b, (SELECT catId, title FROM categories WHERE parentId = :parent_id LIMIT :limit OFFSET :offset) as a"
" WHERE b.categoryId = a.catId"
" ORDER BY b.categoryId"
-^-

MySQL Temporary Table query - add calculated column to table calculated in select

I'm trying to make a temporary table from a query with another column which is calculated in the query...
Here is my query:
asprintf(&query,
"CREATE TEMPORARY TABLE IF NOT EXISTS task_tab (PRIMARY KEY(event_id))"
"SELECT V.id as event_id, V.event_time, D.user, V.location FROM device D "
"JOIN device_service DS ON D.id = DS.device_id "
"JOIN services S ON DS.service_id = S.id "
"JOIN device_event V ON D.id = V.device_id "
"WHERE V.store = 'event_box' AND S.options = 'box_length' AND (S.flags & 1 = 1)"
"AND V.event_time + (IF(S.value IS NULL, %d, S.value) * 86400000) <= %llu"
"AND D.id IN ( SELECT D.id FROM device D "
"JOIN device_service DS ON D.id = DS.device_id "
"JOIN services S ON DS.service_id = S.id "
"WHERE S.action = 'delete' AND (S.flags & 1 = 1)",
app_config->def_expire, current_epoch_ms);
I'd like to create a column 'expire_time' in this temporary table, and store the result of this part of the query in that column:
V.event_time + (IF(S.value IS NULL, %d, S.value) * 86400000)
Any ideas?
Add
V.event_time + (IF(S.value IS NULL, %d, S.value) * 86400000) AS `expire_time`
to your SELECT filed list

Combining 3 querys on SQL

I have a table with both, Products and Sevices. And I store the products brands, product names and services names on separate tables.
I get the list of Services with this Query:
SELECT maeinvs.idInv, CONCAT(services.Service, " ", maeinvs.Detail) AS Name
FROM maeinvs
INNER JOIN services
ON services.idService = maeinvs.idService
And the list of Products with this one:
SELECT maeinvs.idInv, CONCAT(brands.Brand, " ", products.Product, " ", maeinvs.Detail) AS Name
FROM maeinvs
INNER JOIN products
ON products.idProduct = maeinvs.idProduct
INNER JOIN brands
ON brands.idBrand = maeinvs.idBrand
I need to get a Query like this, but instead of the idInv field I need the actual Name of the Product or Service. Any ideas?
SELECT idInv, Desc, Qnty, Price
FROM invoicedetails
WHERE idInvoice = $id
Thanks.
SELECT maeinvs.idInv, CONCAT(services.Service, " ", maeinvs.Detail) AS Name,
"" AS Desc, 0 AS Qnty, 0 AS Price
FROM maeinvs
INNER JOIN services
ON services.idService = maeinvs.idService
UNION
SELECT maeinvs.idInv, CONCAT(brands.Brand, " ", products.Product, " ", maeinvs.Detail) AS Name,
"" AS Desc, 0 AS Qnty, 0 AS Price
FROM maeinvs
INNER JOIN products
ON products.idProduct = maeinvs.idProduct
INNER JOIN brands
ON brands.idBrand = maeinvs.idBrand
UNION
SELECT idInv,
"" AS Name,
Desc, Qnty, Price
FROM invoicedetails
WHERE idInvoice = $id
I've written what I've changed on next line
As the columns match each other, UNION will work.
I still don't know how to do it on a single query (I just know the basics; an Alias?) but solved it doing a VIEW and then a JOIN with my invoicedetails table.
VIEW:
SELECT maeinvs.idInv, CONCAT(services.Service, " ", maeinvs.Detail) AS Name
FROM maeinvs
INNER JOIN services
ON services.idService = maeinvs.idService
UNION
SELECT maeinvs.idInv, CONCAT(brands.Brand, " ", products.Product, " ", maeinvs.Detail) AS Name
FROM maeinvs
INNER JOIN products
ON products.idProduct = maeinvs.idProduct
INNER JOIN brands
ON brands.idBrand = maeinvs.idBrand
QUERY:
SELECT viewnames.Name, invoicedetails.Desc, invoicedetails.Qnty, invoicedetails.Price
FROM invoicedetails
INNER JOIN viewnames ON viewnames.idInv = invoicedetails.idInv
WHERE invoicedetails = $id

MySQL Sum() from derived column

I am joining product and cart table to calculate for the total price for each cart. Here is my sql statement:
String sql = "SELECT p.productID, p.productName, p.productPrice, c.quantity, p.productPrice * c.quantity as new_unit_price, SUM(p.productPrice * c.quantity) AS totalPrice"
+ " FROM sm_product p INNER JOIN sm_cart c "
+ "ON p.productID = c.productID"
+ " WHERE c.custName = '" + custName + "'";
I derived a column named new_unit_price by multiplying the quantity from cart table and product price from product table. Then I want to use the derived column which is new_unit_price to sum up the price of all item in the cart. I get the data from the column in database by:
double subItemTotal = rs.getDouble("new_unit_price");
double totalPrice = rs.getDouble("totalPrice");
My new_unit_price works. But unfortunately, my sum does not works. It's still 0. Does anybody know how can I sum up the value from derived column? Thanks in advance.
To use the SUM() function, you'll need to do a GROUP BY at the end of your statement.
This should get your overall cart total:
String sql = "SELECT c.custname "
+ ", SUM(p.productPrice * c.quantity) AS totalPrice"
+ " FROM sm_product p INNER JOIN sm_cart c "
+ "ON p.productID = c.productID"
+ " AND c.custName = '" + custName + "'"
+ " GROUP BY c.custname;"
Also, I changed the WHERE to an AND so it is evaluated earlier and should make the query faster.
If you want the new_unit_price and the cart total in the same query, you have to go back into the tables again to get that data. Something like this should work:
String sql = "SELECT p.productID, p.productName, p.productPrice, c.quantity "
+ ", p.productPrice * c.quantity as new_unit_price, total.totalPrice FROM "
+ "( "
+ "SELECT c.custname "
+ ", SUM(p.productPrice * c.quantity) AS totalPrice"
+ " FROM sm_product p INNER JOIN sm_cart c "
+ "ON p.productID = c.productID"
+ " AND c.custName = '" + custName + "'"
+ " GROUP BY c.custname"
+ ") AS total "
+ "INNER JOIN sm_cart c "
+ "ON total.custname=c.custname "
+ "INNER JOIN sm_product p "
+ "ON p.productID = c.productID "