How to SET user defined variables in dynamic SQL query? - mysql

Where does the SET assignment (SET #running_total_available := 0;) go when using dynamic SQL as in my query below?
My query works fine as shown, but the "#running totals..." crash the query when I use SET #running_total_available := 0
and reset each row to "0" without the use of SET.
I'm stumped. Thanks!
$sql = "
SELECT
SQL_CALC_FOUND_ROWS
#running_total_available := 0,
product_source,
username,
product_short_name,
noci_count,
item_listing_id,
IF(num_purchased=0,'', num_purchased) AS num_purchased ,
IF(num_available=0,'', num_available) AS num_available,
IF(num_sold=0,'', num_sold) AS num_sold,
i.tot_items,
date(date_listing_noci) AS date_listing_noci,
IFNULL(date(date_listing_removed),'') AS date_listing_removed,
#running_total_purchased:=#running_total_purchased + i.num_purchased AS running_total_purchased,
#running_total_available:=#running_total_available + i.num_available AS running_total_available,
#running_total_sold:=#running_total_sold + i.num_sold AS running_total_sold,
#running_total_item:=#running_total_item + i.num_sold + i.num_available AS running_total_item,
#running_total_noci:=#running_total_noci + i.noci_count AS running_total_noci
FROM
(SELECT
product_source,
item_listing_id,
p.product_short_name,
username,
noci_count,
IF(num_purchased=0,0,num_purchased) AS num_purchased,
IFNULL(num_available,0) AS num_available,
IFNULL(num_sold,0) AS num_sold,
IFNULL(num_sold,0) + IFNULL(num_available,0) AS tot_items,
date(date_listing_noci) AS date_listing_noci,
IFNULL(date(date_listing_removed),'') AS date_listing_removed
FROM `investigation`
JOIN product p USING (product_id)
WHERE 1 ";
*** dynamic constructs here ***
# close query
$sql.= " ) i ";
$result = $objDbMysqli->query($sql);

Initialize it in a cross-joined subquery:
SELECT
...
FROM (
...
JOIN product p USING (product_id)
WHERE 1
) i
CROSS JOIN (select #running_total_available := 0) initvars
Use it on your own risk because the execution order is not guaranteed.

Related

Hibernate Native Query fails but SQL Query works

I have this query using hibernate:
#Query(value = "BEGIN SET #rank = 1; CREATE TEMPORARY TABLE IF NOT EXISTS results "
+ "SELECT User.userId, User.username, #rank FROM User WHERE User.username = :searchString ;"
+ "SET #rank = 2; INSERT INTO results (SELECT User.userId, User.username, #rank FROM Following "
+ "JOIN User ON Following.followsId = User.userId " + "JOIN UserProfile ON UserProfile.userProfileId = User.userProfileId "
+ "WHERE Following.userId = :userId AND User.username LIKE :searchString "
+ "ORDER BY UserProfile.followsCount DESC); "
+ "SET #rank = 3; INSERT INTO results (SELECT User.userId, User.username, #rank FROM User "
+ "JOIN UserProfile ON UserProfile.userProfileId = User.userProfileId "
+ "WHERE User.username LIKE :searchString ORDER BY UserProfile.followsCount DESC); "
+ "SELECT User.* FROM results JOIN User ON User.userId = results.userId ORDER BY #rank DESC LIMIT 50; "
+ "DROP TEMPORARY TABLE results; END;", nativeQuery = true)
List<User> findLike(#Param("searchString") String searchString, #Param("userId") Long userId);
When I run it, i'm told that it could not extract the result set (by JUNIT) and in the console
16:32:24.554 [main] ERROR o.h.e.jdbc.spi.SqlExceptionHelper - 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 'SET #rank = 1; CREATE TEMPORARY TABLE IF NOT EXISTS results SELECT User.userId, ' at line 1
I turned hibernate.show_sql=true and even ran the query that was logged to the console using mysqlworkbench and it works.
Note that this query is running in a interface that is defined as such:
public interface IUserJpaDao extends JpaRepository<User, Long>, JpaSpecificationExecutor<User>
Any ideas why it works in MySqlWorkbench and not in hibernate?

SET two variables in SELECT statement - MySQL

I am using below code which is executing in mysql but giving error while hitting through java program as java program cannot read semicolons ... for java these are 3 statements . I need to execute this query ( setting both variable and then selecting in one query):
set #row_number:=0;set #PROMOTION_ID_NO:='';
SELECT
#row_number:=CASE
WHEN #PROMOTION_ID_NO=PD.PROMOTION_ID THEN #row_number + 1
ELSE 1
END AS SEQ,
#PROMOTION_ID_NO:=PD.PROMOTION_ID AS PROMOTION_ID,
PD.CONDITION_CODE,
PM.PROMOTION_code,
PD.CONDITION_TYPE
FROM
POS_PROMOTION_DISCOUNT PD , POS_PROMOTION_MASTER PM WHERE
PD.PROMOTION_ID = PM.PROMOTION_ID
AND PD.STORE_NO = 'G121';
You can move the SET statement(s) to a separate Derived Table, and do a CROSS JOIN of that table with the other table(s).
Please don't use Old comma based Implicit joins and use Modern Explicit Join based syntax. I have changed to use JOIN .. ON instead.
Try the following:
SELECT
#row_number:=CASE
WHEN #PROMOTION_ID_NO=PD.PROMOTION_ID THEN #row_number + 1
ELSE 1
END AS SEQ,
#PROMOTION_ID_NO:=PD.PROMOTION_ID AS PROMOTION_ID,
PD.CONDITION_CODE,
PM.PROMOTION_code,
PD.CONDITION_TYPE
FROM
POS_PROMOTION_DISCOUNT PD
JOIN POS_PROMOTION_MASTER PM ON PD.PROMOTION_ID = PM.PROMOTION_ID
CROSS JOIN (SELECT row_number:=0, #PROMOTION_ID_NO:='') AS user_init
WHERE
PD.STORE_NO = 'G121';

MySql : How to get the four unique results only?

I am trying to get the these four highlighted results only. I tried grouping them but still not getting the required results.
The query is :-
Set #filter := 0.00;
SELECT autorates2.ID, autorates2.Car, autorates2.Origin , autorates2.Destination, autorates2.Carrier,
#FuelLevy := ( autorates2.Buy * Carrier.FuelLevy) + autorates2.Buy AS 'AfterFuelLevy',
#GST :=(#FuelLevy * 0.10) + #FuelLevy AS 'AfterGST',
#filter := (Select Margin.MarginPer from Margin where #GST between Margin.Low and Margin.High ),
#Margin := (#filter * #GST) + #GST AS 'Sell',
autorates2.OriginType, autorates2.DestinationType, CONCAT(autorates2.OriginType, autorates2.DestinationType) as'ser'
from Margin, Carrier
RIGHT JOIN autorates2 on autorates2.Carrier = Carrier.Carrier
Where autorates2.Origin = 'Melbourne' AND autorates2.Destination = 'Sydney' AND autorates2.Car = '4WD/Van' AND Carrier.Disabled = 0 AND autorates2.GoodsAllowed = 0
Group by ser
ORDER by MIN(Sell),ser
And the output I get is where the highlighted one are wrong results:-
This is the actual results that needed.
Table 1:
Table 2:
Table 3:
use corelated-sub query like below way, as you not shared your all source column name so i guess price is a column
select * from yourtable t1 where price in
(
select min(price) from yourtable t2 where t1.car=t2.car
and t1.depot=t2.depot and t1.door=t2.door
and t1.destinationtype=t2.destinationtype and t1.ser=t2.ser
)

sql rank row results

I"m trying to add a new col that shows the rank (or sequence) of row results by date.
I've written:
SELECT
#row_number:=(CASE
WHEN #member_id = lh.member_id and lc.ladder_advocacy is not null
THEN #row_number + 1
when #member_id = lh.member_id and lc.ladder_advocacy is null then "null"
ELSE 1 /* there is an error here - i need it to return a 1 if not null, then 2 for the 2nd instance, etc */
END) AS rank_advocacy,
#member_id:=lh.member_id AS member_id,
lh.ladder_change,
lc.name,
lc.ladder_advocacy,
lc.ladder_elected,
lc.ladder_policy,
lc.ladder_engagement,
lc.ladder_newventure,
lc.ladder_collective,
lc.is_trigger
FROM
leenk_ladder_history AS lh
LEFT JOIN
leeds_so.leenk_ladder_config AS lc ON lh.ladder_config_id = lc.id
WHERE
ladder_change = 1 AND trigger_active = 1
ORDER BY member_id, trigger_event_date DESC;
There is an error at row 4, and I'm not sure how to fix it. For the first result, I want to return 1. for the second results, I want to return #row_number + 1. Third result, #row_number+2 (etc).
How do I achieve this?
I don't understand how the condition lc.ladder_advocacy is not null is being used. However, the basic structure is:
SELECT (#row_number = IF(#member_id = lh.member_id, #row_number + 1
IF(#member_id := lh.member_id, 1, 1)
)
) as rank_advocacy,
lh.ladder_change,
. . .
Some really important points:
You need to assign #member_id and #row_number in the same expression. MySQL (as with all other databases) does not guarantee the order of evaluation of expressions.
In more recent versions of MySQL, I think the ORDER BY needs to go in a subquery, with the variable expressions in the outer query.

mysql create view with mysql query that contains variable

I have the below syntax that I want to use to create a MySQL view:
create view `ViewName` as (select
v_starting.callingname,
v_starting.geofence,
v_starting.`updatetime`,
#lastGroup := #lastGroup + if( #lastAddress = v_starting.geofence
AND #lastVehicle = v_starting.callingname, 0, 1 ) as GroupSeq,
#lastVehicle := v_starting.callingname as justVarVehicleChange,
#lastAddress := v_starting.geofence as justVarAddressChange
from
v_starting,
( select #lastVehicle := '',
#lastAddress := '',
#lastGroup := 0 ) SQLVars
order by
v_starting.`updatetime` )
This fails with error:
#1351 - View's SELECT contains a variable or parameter
How can I get around this? Thanks a million.
As documented under CREATE VIEW Syntax:
A view definition is subject to the following restrictions:
[ deletia ]
The SELECT statement cannot refer to system or user variables.
Think you would need to do this using a subselect to count the records.
Something like this:-
SELECT v_starting.callingname,
v_starting.geofence,
v_starting.`updatetime`,
Sub1.PrevRecCount ASGroupSeq
FROM v_starting
INNER JOIN (SELECT a.updatetime, COUNT(DISTINCT b.callingname, b.geofence ) AS PrevRecCount
FROM v_starting a
LEFT OUTER JOIN v_starting b
ON a.updatetime > b.updatetime
AND a.callingname != b.callingname
AND a.geofence != b.geofence
GROUP BY a.updatetime) Sub1
Not 100% sure about this as I am dubious about how you are ordering things to get your count presently.
for variable using, try to use a stored procedure or a custom function