MySQL if not null order by - mysql

I am writing a stored procedure for my business directory application. The browse listings form has a select menu that lets users order listings by certain fields. If the sortField parameter is not null, it should order by that column in the order specified by the sortOrder(asc or desc) parameter. If the sortField parameter is specified, then the sortOrder field will always be specified with it. I am getting an error that says "Check the syntax near IF sortField != NUL .... ELSE ORDER BY l.lis"
Here is my query:
CREATE PROCEDURE `ListingsRetrieve` (
IN listingId INT(15),
IN categoryID INT(15),
IN regionId INT(15),
IN memberId INT(15),
IN keywords VARCHAR(250),
IN filterDistance INT(3),
IN latitude DOUBLE,
IN longitude DOUBLE,
IN sortField VARCHAR(16),
IN sortOrder VARCHAR(16),
IN page INT(15),
IN perPage INT(3)
)
BEGIN
SELECT
l.listing_id AS id, l.member_id, l.category_id, l.banner_id, l.thumbnail_id, l.logo_id, l.title AS listing_title, l.description, l.address, l.city, l.zip, UNIX_TIMESTAMP(l.date_submitted) AS date_submitted, l.latitude, l.longitude,l.phone,l.website, l.phone, l.contact_email, l.facebook_url, l.twitter_url, l.slug AS listing_slug,
l.sunday_open, l.sunday_close, l.monday_open, l.monday_close, l.tuesday_open, l.tuesday_close, l.wednesday_open, l.wednesday_close, l.thursday_open, l.thursday_close, l.friday_open, l.friday_close, l.saturday_open, l.saturday_close,
( 6371 * acos( cos( radians(latitude) ) * cos( radians( l.latitude) ) * cos( radians( l.longitude ) - radians(longitude) ) + sin( radians(latitude) ) * sin( radians( l.latitude ) ) ) ) AS distance,
c.category_id AS cat_id, c.slug AS cat_slug, c.icon AS cat_icon,
r.region_id AS region_id, r.title AS region_title, r.slug AS region_slug, (FLOOR((AVG(rev.score)) * 2) / 2) AS stars,
(SELECT
AVG(FLOOR(AVG(rev.score) * 2) / 2)
FROM
reviews AS r
INNER JOIN
listings AS l ON r.review_listing_id = l.listing_id
) as totalAvg,
((COUNT(rev.review_id) / (COUNT(rev.review_id)+5)) * (FLOOR((AVG(rev.score)) * 2) / 2) + (5 / (COUNT(rev.review_id)+5)) * AVG(rev.score)) AS rating,
b.attachment_id AS banner_id, b.file_path AS banner_path,
t.attachment_id AS thumbnail_id, t.file_path AS thumbnail_path,
lgo.attachment_id AS logo_id, lgo.file_path AS logo_path,
CONCAT_WS('/', r.slug, c.slug, l.slug, l.listing_id) AS listing_uri
FROM listings AS l
LEFT JOIN categories AS c ON l.category_id = c.category_id
LEFT JOIN regions AS r ON l.region_id = r.region_id
LEFT JOIN reviews AS rev ON l.listing_id = rev.review_listing_id
LEFT JOIN attachments AS b ON l.banner_id = b.attachment_id
LEFT JOIN attachments AS t ON l.thumbnail_id = t.attachment_id
LEFT JOIN attachments AS lgo ON l.logo_id = lgo.attachment_id
WHERE (listingId IS NULL or l.listing_id = listingId) AND
(categoryId IS NULL or l.category_id = categoryId) AND
(regionId IS NULL or l.region_id = regionId) AND
(memberId IS NULL or l.member_id = memberId) AND
(keywords IS NULL or MATCH(l.title,l.description,r.title,c.title) AGAINST(keywords) AND
(filterDistance IS NULL OR distance = filterDistance)
IF sortField != NULL THEN
ORDER BY sortField sortOrder
ELSE
ORDER BY l.listing_id DESC
IF listingId != NULL THEN
LIMIT 1;
ELSE
LIMIT (IF page > 1 THEN ((page - 1) * perPage) ELSE 0),perPage
END IF;
END //

You cannot build dynamic queries this way.
You can compose the query as a string in a variable then use the string to prepare a statement and execute it:
# Put the common part of the query in a string. Take care to not include
# the variable names but use CONCAT() to join their *values* into the SQL syntax.
# Or, if possible, replace them with question marks (?) and pass
# them to EXECUTE as parameter values (see below or read the documentation)
SET #sql = 'SELECT l.listing_id AS id, ... OR distance = filterDistance)';
# Add the ORDER BY clause
IF sortField IS NOT NULL THEN
SET #sql = CONCAT(#sql, ' ORDER BY ', sortField, ' ', sortOrder);
ELSE
SET #sql = CONCAT(#sql, ' ORDER BY l.listing_id DESC');
END IF;
# Add the LIMIT clause; it uses parameters
SET #sql = CONCAT(#sql, ' LIMIT ?, ?');
# Compute the values of parameters to use in the LIMIT clause
IF listingId IS NOT NULL THEN
SET #start = 1;
SET #limit = 1;
ELSE
# Make sure #start is not negative
SET #start = MAX(0, (page - 1) * perPage);
SET #limit = perPage;
END IF;
# Use #sql to prepare a statement
PREPARE stmt1 FROM #sql;
# Run the prepared statement with parameters
EXECUTE stmt1 USING #start, #limit;
# Can run the prepared statement again, with different parameters if needed
# ...
# Remove the prepared statement when it is not needed any more
DEALLOCATE PREPARE stmt1;

Related

Use the result of a MySQL query, as a variable, with the IN-operator

Looking for a way to return a variable that can be used inside a IN-operator.
My current result returns: 1,2,3,
but I guess the variable should be more like this: '1','2','3' to be able to use it.
Is this possible?
Or should I try something else like explode, save the query,...
-- init vars
SET #export_date = '2022-06-20';
SET #order_ids = '';
-- Tasks on given day
SELECT * FROM tasks WHERE task_execution_date = #export_date;
-- method 1
SET #order_ids = (SELECT GROUP_CONCAT(DISTINCT task_order SEPARATOR ',' ) FROM tasks WHERE task_execution_date = #export_date);
SELECT #order_ids; -- "1,2,3"
-- method 2
SET #order_ids = (SELECT GROUP_CONCAT(DISTINCT '' + cast( task_order AS CHAR(50)) +'' ) FROM tasks WHERE task_execution_date = #export_date);
SELECT #order_ids; -- "1,2,3"
-- method 3
SET #order_ids = (SELECT GROUP_CONCAT( DISTINCT + '\'' + CAST(task_order AS CHAR (100)) + '\'') FROM tasks WHERE task_execution_date = #export_date);
SELECT #order_ids; -- "1,2,3"
-- Orders by tasks
SELECT * from orders WHERE ordr_id IN (#order_ids); -- returns only one result
-- SELECT * from orders WHERE ordr_id IN #order_ids; -- error
SELECT * from orders WHERE ordr_id IN ('1', '2', '3'); -- works
SELECT * from orders WHERE ordr_id IN (SELECT DISTINCT task_order FROM tasks WHERE task_execution_date = #export_date); -- works
-- Also needed:
-- goods by orders
-- good_adrs by goods
If You really, really, I mean REALLY know that these variables can't be evil, then You can build and execute raw query:
SET #export_date = '2022-06-20';
SET #order_ids = (SELECT GROUP_CONCAT(DISTINCT task_order SEPARATOR ',' ) FROM tasks WHERE task_execution_date = #export_date);
SET #query = CONCAT('SELECT * from orders WHERE ordr_id IN (', #order_ids, ');');
PREPARE stmt FROM #query;
EXECUTE stmt;

Is 1.3s Slow for a Query with GPS, Text, & Ranked Keywords?

I've got a MySQL database with about 80K products, 300 store locations, and pricing info. Some products have prices, some don't. I'm running search on the product names (text), tags associated with them (text), ranks (integers), omit_tags that searches & products that don't go together, and geolocation based on a users location and distance they specify from the stores location. My search times are averaging 1.3s to return 10 results. Would this be considered slow?
Here's what my query looks like.
SELECT DISTINCT t3.prod_id,
t3.awaiting_approval,
t3.brand,
t3.prod_name,
t3.size,
t3.units,
t3.category,
t3.image,
t3.url,
t3.quantity,
t3.rank,
t3.word_count,
t3.word_count
FROM ((SELECT item_info_mem.prod_id,
item_info_mem.awaiting_approval,
item_info_mem.prod_name,
item_info_mem.brand,
item_info_mem.size,
item_info_mem.units,
item_info_mem.category,
(SELECT rank
FROM search_tags_mem
WHERE prod_id = item_info_mem.prod_id
AND tag = "bread"
ORDER BY rank
LIMIT 1) AS
rank,
(SELECT image
FROM images_mem
WHERE prod_id = item_info_mem.prod_id
ORDER BY id
LIMIT 1) AS
image,
(SELECT url
FROM urls_mem
WHERE prod_id = item_info_mem.prod_id
AND disabled IS NULL
ORDER BY id DESC
LIMIT 1) AS
url,
(SELECT quantity
FROM shopping_list_mem
WHERE user_id = "1"
AND prod_id = item_info_mem.prod_id
ORDER BY id
LIMIT 1) AS
quantity,
( Substrcount(Lcase(item_info_mem.prod_name), Lcase("bread"))
+ Substrcount(Lcase(item_info_mem.brand), Lcase("bread")) ) AS
word_count,
( Substrcheck(Lcase(item_info_mem.prod_name),
Lcase(item_info_mem.brand), Lcase("bread")) ) AS
word_count_unique
FROM item_info_mem
WHERE NOT EXISTS (SELECT id
FROM search_tags_omit_mem
WHERE prod_id = item_info_mem.prod_id
AND tag = "bread"
ORDER BY id DESC
LIMIT 1)
AND ( item_info_mem.prod_name REGEXP "bread"
OR item_info_mem.brand REGEXP "bread" )
AND EXISTS(SELECT scans_mem.scan_id
FROM scans_mem,
stores_mem
WHERE scans_mem.price IS NOT NULL
AND scans_mem.expired IS NULL
AND item_info_mem.prod_id = scans_mem.prod_id
AND NOT
EXISTS (SELECT
user_stores_disabled_mem.user_id
FROM
user_stores_disabled_mem
,
stores_mem
WHERE scans_mem.store_id =
stores_mem.id
AND
user_stores_disabled_mem.chain =
stores_mem.chain
AND
user_stores_disabled_mem.user_id =
1)
AND ( Sqrt(Pow(111 * (stores_mem.gps_lat
- 40.748080
), 2)
+ Pow(111 * (stores_mem.gps_lng -
-73.990533) *
Cos(
40.748080 /
57.3)
,
2)) <= (SELECT user_mem.distance
FROM user_mem
WHERE id = 1))
AND stores_mem.id = scans_mem.store_id))
UNION ALL
(SELECT item_info_mem.prod_id,
item_info_mem.awaiting_approval,
item_info_mem.prod_name,
item_info_mem.brand,
item_info_mem.size,
item_info_mem.units,
item_info_mem.category,
search_tags_mem.rank,
(SELECT image
FROM images_mem
WHERE prod_id = item_info_mem.prod_id
ORDER BY id
LIMIT 1) AS image,
(SELECT url
FROM urls_mem
WHERE prod_id = item_info_mem.prod_id
AND disabled IS NULL
ORDER BY id DESC
LIMIT 1) AS
url,
(SELECT quantity
FROM shopping_list_mem
WHERE user_id = "1"
AND prod_id = item_info_mem.prod_id
ORDER BY id
LIMIT 1) AS
quantity,
( Substrcount(Lcase(item_info_mem.prod_name), Lcase("bread"))
+ Substrcount(Lcase(item_info_mem.brand), Lcase("bread")) ) AS
word_count,
( Substrcheck(Lcase(item_info_mem.prod_name),
Lcase(item_info_mem.brand), Lcase("bread")) ) AS
word_count_unique
FROM item_info_mem,
search_tags_mem,
scans_mem,
stores_mem
WHERE NOT EXISTS (SELECT id
FROM search_tags_omit_mem
WHERE prod_id = item_info_mem.prod_id
AND tag = "bread"
ORDER BY id DESC
LIMIT 1)
AND scans_mem.price IS NOT NULL
AND scans_mem.expired IS NULL
AND item_info_mem.prod_id = search_tags_mem.prod_id
AND search_tags_mem.tag = "bread"
AND item_info_mem.prod_id = scans_mem.prod_id
AND NOT EXISTS (SELECT user_stores_disabled_mem.user_id
FROM user_stores_disabled_mem,
stores_mem
WHERE scans_mem.store_id = stores_mem.id
AND user_stores_disabled_mem.chain =
stores_mem.chain
AND user_stores_disabled_mem.user_id = 1)
AND ( Sqrt(Pow(111 * (stores_mem.gps_lat - 40.748080), 2)
+ Pow(111 * (stores_mem.gps_lng - -73.990533) * Cos(
40.748080 /
57.3)
,
2)) <= (SELECT user_mem.distance
FROM user_mem
WHERE id = 1))
AND stores_mem.id = scans_mem.store_id)) t3
ORDER BY -rank DESC,
word_count_unique DESC,
word_count DESC,
Field(t3.category, "food", "grocery", "pantry, household & pets",
"confectionery and grocery") DESC,
Length(prod_name),
brand
LIMIT 0, 10
````
There's a lot of reasons why the script being fast or slow.
PC Specs capabilities, DB Server version, DB Structure including indexes, Query structure also with network connection between server and client.
If you are asking Would this be considered slow? with 80k records my answer is NO
This Guide will help you about Query Optimization.

T-SQL with ORDER BY differences in stored procedure reveal GROUP BY issues

I've got a data problem seen by my public demo site:
http://cbmiweb.com/GmapsV3/opedemo3.aspx
The default ORDER appears OK but changing to Order By Total#Awards exposes the problem clearly yet I am stuck on how to fix it.
The web page exposes a link to the raw data returned (fires the stored procedure) where you can see the data problem:
http://cbmiweb.com/CBMI.WebAPIservice/api/markers/GetGrants/2
In short, why does #Sort = 1 "group" Institution="BISHOP STATE COMMUNITY COLLEGE" properly but when using #Sort = 2, this entity is "interleaved" with other institutions with 8 awards?
Using SQL Server 2008, here is the stored procedure which orders the final result set 3 different ways (the problem is most noticeable with #Sort = 2) shown above:
ALTER PROCEDURE [dbo].[FLAS2_List_Awards_V1]
-- EXECUTE dbo.FLAS2_List_Awards_V1 2
(#Sort int = 1 -- 1 = descending order on TotalAmount
-- 2 = descending order on TotalAwards
-- 3 = ascending order on Institution
)
AS
CREATE TABLE #TempMarkers
(
ID nchar(6) NOT NULL,
Institution nvarchar(255) NOT NULL,
Street nvarchar(255) NULL,
City nvarchar(255) NULL,
State nvarchar(255) NULL,
Zip nvarchar(255) NULL,
Latitude decimal(28, 18) NULL,
Longitude decimal(28, 18) NULL,
TotalAwards decimal(16, 0) NULL,
TotalAmount decimal (16, 0) NULL
)
INSERT INTO #TempMarkers(ID, Institution, Street, City, State, Zip,
Latitude, Longitude, TotalAwards, TotalAmount)
SELECT DISTINCT
C.ID, C.InstitutionName,
NULL AS street, NULL AS city, NULL AS state, NULL AS zip,
NULL As Latitude, NULL As Longitude,
COUNT(DISTINCT o.GrantNumber) as TotalAwards,
SUM(DISTINCT o.TotalObligatedAmount) as TotalAmount
FROM
dbo.FLAS2_Schools2 C
INNER JOIN
dbo.FLAS2_Grants o ON c.id = o.ID
-- where o.ID in (100654,100724)
GROUP BY
C.ID, C.InstitutionName
--,Z.Lat
-- ,Z.Long
UPDATE #TempMarkers
SET Street = x.street,
City = x.city,
State = x.state,
Zip = x.zip
FROM
dbo.FLAS2_Schools2 X
WHERE
X.ID = #TempMarkers.ID
AND X.InstitutionName = #TempMarkers.Institution
UPDATE #TempMarkers
SET Latitude = Z.lat,
Longitude = Z.Long
FROM dbo.ZipCodesPreferred Z
WHERE Z.ZipCode = #TempMarkers.Zip
--SELECT * FROM #TempMarkers
IF #Sort = 1
BEGIN
SELECT DISTINCT
Marker.ID, Marker.Institution,
Marker.Street, Marker.City, Marker.State, Marker.Zip,
Marker.Latitude, Marker.Longitude,
Marker.TotalAmount, Marker.TotalAwards,
Award.GrantNumber as GrantNumber,
Award.TotalObligatedAmount as GrantAmount
FROM
#TempMarkers Marker
INNER JOIN
dbo.FLAS2_Grants Award ON Marker.ID = Award.ID
ORDER BY
Marker.TotalAmount DESC, GrantAmount DESC
FOR XML AUTO, ROOT('root')
END
IF #Sort = 2
BEGIN
SELECT
Marker.ID, Marker.Institution,
Marker.Street, Marker.City, Marker.State, Marker.Zip,
Marker.Latitude, Marker.Longitude,
Marker.TotalAmount, Marker.TotalAwards,
Award.GrantNumber as GrantNumber,
Award.TotalObligatedAmount as GrantAmount
FROM
#TempMarkers Marker
INNER JOIN
dbo.FLAS2_Grants Award ON Marker.ID = Award.ID
ORDER BY
Marker.TotalAmount DESC, GrantAmount DESC
FOR XML AUTO, ROOT('root')
END
IF #Sort = 3
BEGIN
SELECT
Marker.ID, Marker.Institution,
Marker.Street, Marker.City, Marker.State, Marker.Zip,
Marker.Latitude, Marker.Longitude,
Marker.TotalAmount, Marker.TotalAwards,
Award.GrantNumber as GrantNumber,
Award.TotalObligatedAmount as GrantAmount
FROM
#TempMarkers Marker
INNER JOIN
dbo.FLAS2_Grants Award ON Marker.ID = Award.ID
ORDER BY
Marker.Institution, GrantAmount DESC
FOR XML AUTO, ROOT('root')
END
I found the solution. I just needed to ponder it a bit more after a break...
The ORDER BY clause was insufficient. When the primary sort column is something like TotalAwards, there are clearly going to be some "ties" (i.e. multiple entities having the same count of awards). So it is necessary to sort secondarily on the name column to remove the "interleaving" effect.
Proper ORDER BY clause is as follows:
order by Marker.TotalAwards DESC, Marker.Institution, GrantAmount DESC

Haversine Formula works as Normal SQL but not in stored procedure

I am using haversine formula to find distance between users. It works well as a normal mysql piece of code. But when use the same in a stored procedure it not working and throws 0.00 distances. I don't know why?
This is the working code:
DROP TEMPORARY TABLE if exists temp_tab;
CREATE TEMPORARY TABLE temp_tab(temp_id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,
user_fb_id bigint(20) unique,distance double(15,8) default NULL) CHARSET=utf8;
INSERT into temp_tab (user_fb_id, distance)
SELECT *
FROM (SELECT user_fb_id,
6371 * ACOS(SIN(RADIANS( 11.01684450 )) * SIN(RADIANS(`Latitude`)) + COS(RADIANS( 11.01684450 )) * COS(RADIANS(`Latitude`)) * COS(RADIANS(`Longitude`) - RADIANS( 76.95583210 ))) AS `distance`
FROM `user_login_log`
WHERE user_id <>'1831820984'
HAVING `distance` <= 50
ORDER BY `activity_at` DESC) as t1
GROUP BY user_fb_id;
SELECT * FROM temp_tab;
Normal SQL output:
Stored Procedure output:
Stored Procedure:
DELIMITER ;;
CREATE DEFINER=`up_beta`#`127.0.0.1` PROCEDURE `usp_geo`(user_id bigint(20),latitude double(15,8),longitude double(15,8), dist int(100),location longtext,page int(2),page_size int(2))
BEGIN
Declare limitStart int(10);
Declare limitEnd int(10);
SET #user_id=(SELECT user_id);
set #gen=(select gender from users where user_id=#user_id);
set #latitude = (SELECT latitude);
set #longitude = (SELECT longitude);
set #dist = (SELECT dist);
SET #location=(SELECT location);
set limitStart = ((page*page_size)-page_size);
set limitEnd = page_size ;
set #SNO = ((page - 1)*page_size);
IF #gen='male' then
set #gen='female';
else
set #gen='male';
end if;
DROP TEMPORARY TABLE if exists temp_tab;
CREATE TEMPORARY TABLE temp_tab(temp_id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,
user_id bigint(20) unique,distance double(15,8) default NULL) CHARSET=utf8;
INSERT into temp_tab (user_id, distance)
SELECT * FROM (SELECT user_id, 6371 * ACOS(SIN(RADIANS( #latitude )) * SIN(RADIANS(Latitude)) + COS(RADIANS( #latitude )) * COS(RADIANS(Latitude)) * COS(RADIANS(Longitude) - RADIANS( #longitude ))) AS `distance` FROM `user_log` WHERE user_id <>#user_id HAVING `distance` <= #dist ORDER BY `activity_at` DESC) as t1
GROUP BY user_id;
SELECT * FROM temp_tab;
DROP TEMPORARY TABLE if exists search_tab;
CREATE TEMPORARY TABLE search_tab(temp_id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,
user_id bigint(20) unique,name varchar(500),gender varchar(100),
town longtext,current_location longtext default NULL,is_in_app tinyint(4) default 0,distance double(15,8)) CHARSET=utf8;
INSERT INTO search_tab(user_id,name,gender,town,distance)
SELECT a.user_id, a.name,a.gender,a.home_town,b.distance FROM users a, temp_tab b WHERE a.user_id = b.user_id AND a.gender=#gen AND a.relationship_id NOT IN(2,3,4);
if #location<>'' AND #location<>NULL then
begin
set #city=(select concat('''','%',#location,'%',''''));
set #gender =(select concat('''',#gen,''''));
set #insert_sql = concat('INSERT IGNORE INTO search_tab(user_id,name,gender,town,location)
SELECT a.user_id, a.name,a.gender,a.home_town,b.current_location FROM users a, user_details b WHERE b.current_location LIKE ',#city,' AND a.id = b.user_id AND a.gender=',#gender,' AND a.relationship_id NOT IN(2,3,4)');
PREPARE stmt1 FROM #insert_sql;
EXECUTE stmt1;
end;
end if;
update search_tab set is_in_app=1 where user_fb_id in
(select user_id from users where access_token is not null);
select #a:=#a+1 sno,user_id,name,gender,town,current_location,is_in_app,distance
from search_tab ,(SELECT #a:= #SNO) AS a
limit limitStart,limitEnd;
select count(temp_id)as total_count from search_tab;
end;;
DELIMITER ;

what is causing error (operands should contain 1 column)

I am trying to set myItemId so that I can use it in the concat query. Everything works fine until I add this row
SET myItemID = (SELECT * FROM items i WHERE i.name LIKE '%KW PRE FREE COOLING%');
It then gives me an error of
Operand should contain 1 column(s)
Here is the query that I am working with
CREATE PROCEDURE reportFreeCoolingTempTable (
IN fromDate VARCHAR (50),
IN toDate VARCHAR (50),
IN timeZone VARCHAR (50)
)
BEGIN
DECLARE startDate VARCHAR (50);
DECLARE endDate VARCHAR (50);
DECLARE mylogID INT;
DECLARE myItemID int;
SET startDate = FROM_UNIXTIME(fromDate/1000);
SET endDate = FROM_UNIXTIME(toDate/1000);
SET mylogID = (SELECT logID FROM logs WHERE details LIKE 'FCT%' LIMIT 1);
SET myItemID = (SELECT * FROM items i WHERE i.name LIKE '%KW PRE FREE COOLING%');
SET #sql = NULL;
SET #sql = NULL;
SET #sql = CONCAT(
'SELECT #row:=#row+1 as rownum,
a.logid ,
L1.recordId,
L2.recordId as next_recordId,
L1.completed,
L2.completed as next_completed,
L1.activityId,
L2.activityId as next_activityId,
IF(L1.activityId = L2.activityId,1,NULL) as isError,
TIME_TO_SEC(TIMEDIFF(L2.completed, L1.completed)) / 3600 AS coolingHours,
((L1.item31985 - L1.item31987) * (time_to_sec(timediff(L2.completed, L1.completed)))) / 3600 AS kwDifference,
((L1.item31985 - L1.item31987) * (substr(l.details, instr(l.details , '':'' ) +1))) AS cost,
( (((L1.item31985 - L1.item31987) * (substr(l.details, instr(l.details , '':'' ) +1)))
*(time_to_sec(timediff(L2.completed, L1.completed)) / 3600))) AS costT,
time_to_sec(timediff(''', endDate, ''', ''', startDate, ''')) / 3600 AS totalTimeRange,
CONVERT_TZ(''', startDate, ''', ''UTC'', ''', timeZone, ''') AS startingDate,
CONVERT_TZ(''', endDate, ''', ''UTC'', ''', timeZone, ''') AS endingDate,
DATABASE() AS databaseName
FROM
(SELECT #row:=0)R,
(SELECT T1.completed,
(SELECT MIN(completed)
FROM log1644
WHERE completed > T1.completed) AS next_completed
FROM log',mylogID, ' T1
ORDER BY T1.completed
)TimeOrder
LEFT JOIN log', mylogID, ' L1 ON (L1.completed = TimeOrder.completed)
LEFT JOIN log', mylogID, ' L2 ON (L2.completed = TimeOrder.next_completed)
LEFT JOIN activities a ON L1.activityId = a.activityId
LEFT JOIN logs l ON a.logId = l.logId
Left Join items i ON l.logId = i.logId AND i.name LIKE ''%KW%''
WHERE i.itemID = 31985
AND L1.completed BETWEEN ''', startDate, ''' AND ''', endDate, '''
ORDER BY L1.completed');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END //
DELIMITER ;
Error itself explains (operands should contain 1 column) you need to select the single column from the query in order to set myItemID ,you are selecting all the columns from the items try this
SET myItemID = (SELECT id FROM items i WHERE i.name LIKE '%KW PRE FREE COOLING%' LIMIT 1 );
I assume the you need to set the myItemID to the id column from items where you conditions matches.i have also added LIMIT 1 in order to avoid the error of subquery should return one result
The error is caused because the SET statement expects a single value to be returned from your subquery. Not only can it return multiple values (SELECT *), but it can potentially return multiple rows. Change your query to specify just the single column from your subquery that you want to assign to myItemId, and ensure that it can return only 1 row - like this:
SET myItemID = (SELECT TOP 1 [itemIdColumnName] FROM items i WHERE i.name LIKE '%KW PRE FREE COOLING%');
The 'operand' in your case is "myItemID". It can only hold ONE value. Your SELECT statement returns all the rows in the table (multiple columns). You need to select only the 1 column that represents the ID you are trying to obtain.