Mysql query doesn't work in qt - mysql

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"
-^-

Related

MySQL Query works in phpmyadmin but not in node

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

Long tail where clause at CodeIgniter or Ignited Datatables

I am trying to write a long tail where statement which containing another select query and how I can do it. Currently, I am using Ignited Datatables Library with my CodeIgniter 3 installation.
SELECT ContactId,
ReceiverId,
SenderId,
IF(ReceiverId = 1,
(SELECT first_name
FROM users
WHERE users.id = contacts_connectivity.SenderId),
(SELECT first_name
FROM users
WHERE users.id = contacts_connectivity.ReceiverId)) AS FirstName,
IF(ReceiverId = 1,
(SELECT email
FROM users
WHERE users.id = contacts_connectivity.SenderId),
(SELECT email
FROM users
WHERE users.id = contacts_connectivity.ReceiverId)) AS SenderEmail,
IF(ReceiverId = 1,
(SELECT phone
FROM users
WHERE users.id = contacts_connectivity.SenderId),
(SELECT phone
FROM users
WHERE users.id = contacts_connectivity.ReceiverId)) AS SenderPhone,
IF(ReceiverId = 1,
(SELECT company
FROM users
WHERE users.id = contacts_connectivity.SenderId),
(SELECT company
FROM users
WHERE users.id = contacts_connectivity.ReceiverId)) AS SenderCompany,
ModulesId,
(SELECT ModuleName
FROM modules
WHERE ModuleId = contacts_connectivity.ModulesId) AS ModuledName,
FROM_UNIXTIME(AddedDate, "%m/%d/%Y") AddedDate
FROM contacts_connectivity
WHERE (ReceiverId = 1
OR SenderId = 1)
AND (ReceiverId
OR SenderId NOT IN
(SELECT (ReceiverId
OR SenderId)
FROM contacts_connectivity
WHERE (ReceiverId
OR SenderId) = 1))
I noticed that My query doesn't return any array at all. I already tried to write the where statement like this-
$this->datatables->where("(ReceiverId = ' . $id . ' OR SenderId = ' . $id . ')");
$this->datatables->where(" AND (ReceiverId OR SenderId NOT IN (SELECT (ReceiverId OR SenderId) FROM contacts_connectivity WHERE (ReceiverId OR SenderId) = ' . $id . '");
What am I doing wrong?
You invalid use parameters. Try something like this:
$this->datatables->where("(ReceiverId=$id OR SenderId=$id )");
Second string should be fixed too the same way. Also check that your $id param properly escaped.

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

CASE Statement in where clause in mysql

I'm trying to fetch data from table where I'm using a CASE condition in the WHERE clause and currently I'm using following query:-
$sQuery = "SELECT SQL_CALC_FOUND_ROWS ".str_replace(" , ", " ",
implode(", ", $aColumns))." FROM (select CASE when r.agent_id=24
THEN r.Unit ELSE '--' END AS MyUnit,
CASE when r.agent_id=24 THEN r.landlord_name ELSE '--' END AS landlord_name_new,
r.*,l.loc_name as location,sl.sub_sub_loc as sub_location,
c.category as category,CONCAT(u.first_name, ' ', u.last_name) As agent
from crm_sales r
LEFT JOIN crm_location l ON r.area_location_id=l.loc_id
LEFT JOIN crm_subloc sl ON sl.sub_loc_id = r.sub_area_location_id
LEFT JOIN crm_category c on c.id = r.category_id
LEFT JOIN crm_users u on u.id=r.agent_id
where r.is_active=1 AND r.is_archive=0
AND CASE agent_id WHEN r.agent_id!=24 then r.status=2 else 1=1
group by r.ref) sel
$sWhere
$sOrder
$sLimit
";
Now I want to add one more condition, something like this.
IF(r.agent_id != 24) THEN WHERE r.status=2
EDITED: ADD CASE which i want but error
Fix the case/when clause in your WHERE clause to...
AND CASE WHEN r.agent_id != 24
then r.status = 2
else 1 = 1 end

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