While loop for selecting field names? - mysql

I have a nasty, nasty data layout that I am forced to work with. I finally got a working query using C# and a for loop executing the same query over and over but adjusting which fields are called, but now I am wondering if it is possible to do it with a while loop. I am getting an error, and I am not sure if it is because I am using Faircom / C-tree as the database, or if there is something wrong with my query. I am normally a Mysql user.
the table has 20 fields I care about and want to extract into a csv list. They are codetype1-codetype20 and I want it to be something like value1, value2, value3... where as it is now I get them all back one at a time. Trouble is that codetype1 is dependent on another field to determine where I go look for the info on that code, which is why the case statements.
DROP PROCEDURE IF EXISTS proc_loop_test;
CREATE PROCEDURE proc_loop_test()
SET #index = 1;
WHILE(#index < 21) DO
SELECT Replace(Concat(To_char(apptid), To_char(.#index) ), ' ', '') AS reference_id,
apptid AS a_reference_id,
CASE
WHEN c.ee > 0 THEN d.amt
ELSE insfee.amt
END AS amount,
CASE
WHEN c.ee > 0 THEN Rtrim(e.moneyname)
ELSE insname.namefeecatid
END AS moneyschedule_name,
CASE codetype#index
WHEN 1 THEN rtrim(a.descript)
ELSE rtrim(b.descript0)
END AS description,
CASE codetype#index
WHEN 1 THEN rtrim(a.abbrevdescript)
ELSE rtrim(b.abbrev0)
END AS abbreviated_description,
CASE codetype#index
WHEN 1 THEN rtrim(a.thiscode)
ELSE rtrim(b.thiscode0)
END AS code
FROM meetings
LEFT JOIN
(
SELECT admin.table2.procid,
admin.table2.this_code_id,
admin.v_table1.descript,
admin.v_table1.abbrevdescript,
admin.v_table1.thiscode
FROM admin.table2
INNER JOIN admin.v_table1
ON admin.table2.this_code_id = admin.v_table1.this_code_id) AS a
ON meetings.codeid#index = a.procid
LEFT JOIN
(
SELECT admin.v_table1.descript AS descript0,
admin.v_table1.abbrevdescript AS abbrev0,
admin.v_table1.thiscode AS thiscode0,
admin.v_table1.this_code_id
FROM admin.v_table1) AS b
ON meetings.codeid#index = b.this_code_id
LEFT JOIN
(
SELECT patid AS id,
ee
FROM admin.customer) AS c
ON meetings.patid = c.id
LEFT JOIN
(
SELECT this_code_id AS redid,
eecategoryid,
amt
FROM admin.eeule) AS d
ON c.ee = d.eecategoryid
AND d.redid = b.this_code_id
LEFT JOIN
(
SELECT eecategoryid AS namefeecatid,
moneyname
FROM admin.eeulenames) AS e
ON d.eecategoryid = e.namefeecatid
LEFT JOIN (SELECT pi.customer_id,
pi.primarykk_id AS picid,
pi.primarykk_name,
pi.first_name,
pi.last_name,
i.groupname,
i.ee
FROM admin.v_pir AS pi
LEFT JOIN admin.money AS i
ON pi.primarykk_id = i.insid) AS
ins
ON ins.customer_id = c.id
LEFT JOIN (SELECT this_code_id AS redid,
eecategoryid,
amt
FROM admin.eeule) AS insfee
ON ins.ee = insfee.eecategoryid
AND insfee.redid = b.this_code_id
LEFT JOIN (SELECT eecategoryid AS namefeecatid,
moneyname
FROM admin.eeulenames) AS insname
ON insfee.eecategoryid = insname.namefeecatid
WHERE codeid#index >= 1
END WHILE;
END;
I have never used a while loop, and while I understand somewhat I am supposed to select this to go INTO something, do I need to create a temp table, or can it all just be stored in memory till the end of the loop and returned.
For what it is worth, the entire SELECT query works in C# when you replace the #index with concatenating format " . index . "

Based on the information that you have provided, it is strongly suggested that you reach out to your vendor for this. You're attempting to create a stored procedure, however, using a mySQL proprietary syntax. Stored procedure support is unique to each database vendor. FairCom's c-treeACE SQL actually uses Java for cross platform support and .NET for Windows.
https://docs.faircom.com/doc/jspt/#cover.htm
Stored procedure development requires a strong knowledge of the database layout which is highly application dependent. In this case, many legacy application dependencies may be involved. Again, your best source of information will be your application vendor.

Related

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';

Stored procedure not working as i want

I am trying to make a stored procedure like this
BEGIN
SELECT concat(stationsNavn,' ',city,' ',adresse,' ',postnummer)as navn,id
from AdresseListeBioAnlæg order by stationsNavn,city
inner join bioAlarmer on AdresseListeBioAnlæg.id = bioAlarmer.station;
end
With "as navn,id" i can create it, but i dont get anything, and with "order by stationsNavn,city" i get an error on create. It works fine without any of them like this.
BEGIN
SELECT concat(stationsNavn,' ',city,' ',adresse,' ',postnummer)
from AdresseListeBioAnlæg
inner join bioAlarmer on AdresseListeBioAnlæg.id = bioAlarmer.station;
end
What am i doing wrong?
try this out, I moved the order by and did it by navn and id
BEGIN
SELECT concat(stationsNavn,' ',city,' ',adresse,' ',postnummer)as navn,id
from AdresseListeBioAnlæg
inner join bioAlarmer on AdresseListeBioAnlæg.id = bioAlarmer.station
order by navn, id
end

Use of Pivot in SQL statement?

I'm attempting to create additional columns for when a drive record has multiple other records assigned to the drive. In my attached screenshot, you can see there are three drives where all data is constant, but each has multiple incentives assigned to the drive.
Would a PIVOT function work to create an additional column for the incentive? I'm not looking for something dynamic and I would be OK with hard coding at the most 4 additional columns to have space for five incentives assigned to one drive.
What I would like my results to look like would be:
The last column is how I performed used For XML Path to accomplish it, but it's not exactly what I was looking for.
Here is my SQL statement:
Select
DM.DriveID [DriveID],
DM.FromDateTime [FromDateTime],
Case When DM.OwnerType = 0 Then Acct.Name Else CD.DescLong End As [OwnerName],
Acct.AccountID [AcctID],
Inc.Description [Incentive],
Stuff ((Select ', ' + isnull(EM.Description,'')
From Production.[dbo].EquipmentMaster EM
Inner Join Production.[dbo].EquipmentDetail ED On EM.EquipmentID = ED.EquipmentID And EM.EquipmentType=3
Where ED.DriveID = DM.DriveID
For XML PATH(''), TYPE).value('.', 'varchar(max)')
,1, 2, '') as [XML_Incentives]
From
Production.[dbo].rpt_DriveMaster DM
Left Outer Join Production.[dbo].rpt_Accounts Acct on DM.AccountID=Acct.AccountID
Inner Join Production.[dbo].rpt_CenterDetail CD on DM.CenterID=CD.CenterID
Left Outer Join Production.[dbo].OBI_Incentives Inc on DM.DriveID=Inc.DriveID
Where
DM.DriveID in (658946,597611,651136)
I'm looking at the link provided when marked as duplicate, but is almost like reading Greek to me. I'm trying to modify my SQL to use this as a basis, but not having much luck:
Any chance on some guidance on how this works?
Select
*
From
( Select
DM.DriveID [DriveID],
DM.FromDateTime [FromDateTime],
Case When DM.OwnerType = 0 Then Acct.Name Else CD.DescLong End As [OwnerName],
Acct.AccountID [AcctID],
Inc.Description [Incentive1],
null [Incentive2],
null [Incentive3],
null [Incentive4],
null [Incentive5]
From
Production.[dbo].rpt_DriveMaster DM
Left Outer Join Production.[dbo].rpt_Accounts Acct on DM.AccountID=Acct.AccountID
Inner Join Production.[dbo].rpt_CenterDetail CD on DM.CenterID=CD.CenterID
Left Outer Join Production.[dbo].OBI_Incentives Inc on DM.DriveID=Inc.DriveID
Where
DM.DriveID in (658946,597611,651136)
) as P
Pivot (
min(P.[Incentive])
for P.[DriveID] in ([Incentive1], [Incentive2], [Incentive3])
) as PIV

Comparing dates in iif() in SQL Server

I am trying to use the following query in SQL Server
SELECT [AL].[Subscriptions].Id,
[AL].[Subscriptions].name,
[AL].[Subscriptions].description,
[AL].[Subscriptions].price,
[AL].[Subscriptions].iconFileName,
IIf(a.expiryDate > Now(), 'TRUE', 'FALSE') AS isSubsByUser
FROM [AL].[Subscriptions]
LEFT JOIN (SELECT *
FROM [AL].[UserSubscriptions]
WHERE userId = 13259) AS a
ON Subscriptions.Id = a.itemid;
but always get the error
Error in list of function arguments: '>' not recognized.
Unable to parse query text.
How do I resolve it?
Like Martin Smith said you need to use a case statement. Also it looks like you are only using a couple of fields in the derived table therefor I would suggest not using *. I put a example below.
SELECT [AL].[Subscriptions].Id,
[AL].[Subscriptions].name,
[AL].[Subscriptions].description,
[AL].[Subscriptions].price,
[AL].[Subscriptions].iconFileName,
case when a.expiryDate > GetDate() then 'TRUE' else 'FALSE' end AS isSubsByUser
FROM [AL].[Subscriptions]
LEFT JOIN (SELECT expiryDate, itemid
FROM [AL].[UserSubscriptions]
WHERE userId = 13259) AS a
ON Subscriptions.Id = a.itemid;

mySQL updating but also not updating

I am writing in mySQL/PHP, but have this problem I cannot get my head around. This one PHP script contains two SQL statements. What I am trying to do is update a sports league table (a SQL table called tblrank - which contains many league tables, separated by TableID), and to indicate if the team has gone up or down since the last time it was updated. This first bit of code is bit clunky and probably could've been written better (I could do it in about 6 lines in MSSQL), it works by counting the number of teams that are ranked lower than it, then adding one. It appears to work... sort of, as I will explain later.
update tblrank AS r
set Rank = 1 + (select count(*) from
(select r2.teamID
from tblrank r2
inner join tblrank r3
where r3.TableID = r2.TableID and r3.TableID = $tableid
and (r3.Points > r2.Points
or (r3.Points = r2.Points and r3.TieBreaker > r2.TieBreaker))) as duh
where duh.teamID = r.teamID
and duh.TableID = r.TableID
and r.TableID = $tableid
Then, this bit of code is run to pick the image to display.
update tblrank
set image = case when Rank < LastRank then 'up.png'
when Rank > LastRank then 'down.png'
else 'nomove.png' end
where TableID = $tableid
Now if I run this for $tableid = 1, it works just fine. But, if I run it for $tableid = 2, then all Ranks in the whole of tblRank are set to 1. (Before running it for $tableid = 2, all the ranks are 1, except for records where TableID =1 ). This is obviously not what I want.
Both statements are inside a if(mysql_query($sql)) conditional, so I can verify if they have executed or not.
I use MS SQL a lot more than mySQL so I'm not an expert - can anyone help me with this as I'm baffled! I have checked that both chunks of code do execute. There is no other SQL executed between the two.
Well, I've fixed it, I'm not sure what was wrong, but I've split the update statement up, with a temporary table called rankcount being created and populated first. I did this to make it easier to see what was going on.
create temporary table rankcount (TableID int, UserID int)");
insert into rankcount (TableID, UserID)
select r2.TableID, r2.UserID
from tblRank r2
inner join tblRank r3
where r3.TableID = r2.TableID and r3.TableID = $tableid
and (r3.Points > r2.Points
or (r3.Points = r2.Points and r3.TieBreakerOne > r2.TieBreakerOne))
Then this works...
update userEntryTableRank r
set Rank = 1 + (select count(*) from rankcount rc
where rc.UserID = r.UserID and rc.TableID = r.TableID)
where r.TableID = $tableid
:)
Here's how I'd do it. First initialize all the Rank values to zero.
UPDATE tblrank SET Rank = 0;
UPDATE tblrank r1 JOIN tblrank r2 ON r1.TableID = r2.TableID
SET r1.Rank = r1.Rank + 1
WHERE r1.Points > r2.Points
OR (r1.Points = r2.Points AND r1.TieBreaker > r2.TieBreaker)
The join naturally matches each row r1 to the set of rows r2 with the same table and team, and a lower score. Then it increments Rank by 1 for each of these matching rows.