Check For all index , in GAMS - gams-math

Let 'I' from 1 till 100 , be a set , and w(I), u(I) be a parameters , how can code this statement in GAMS :
if for all I we have w(I)<0 and w(I)*u(I) =0 then display ' converged'.

Display$(smax(I,w(I))<0 and smax(I,w(I)*u(I))=0 and smin(I,w(I)*u(I))=0) 'Converged';

Related

Could someone help me understand the ambiguity here in Postgres?

So I've been trying out PG for a few days, specifically through NpgSQL in dotnet core, but I don't believe that is relevant to my question. I've been writing a couple of update functions. The first one was easy:
CREATE OR REPLACE FUNCTION "Api"."UpdateExpenseReceipt" ( "vReceiptID" UUID , "vTotal" DOUBLE PRECISION , "vTaxPercent" DOUBLE PRECISION , "vShippingCost" DOUBLE PRECISION , "vReceiptDate" TIMESTAMP , "vReference" VARCHAR , "vCurrentToken" UUID )
RETURNS TABLE ( ReceiptID UUID , Total DOUBLE PRECISION , TaxPercent DOUBLE PRECISION , ShippingCost DOUBLE PRECISION , Reference VARCHAR(96) , ReceiptDate TIMESTAMP )
LANGUAGE PLPGSQL
AS $$
DECLARE "iValidReceipt" INTEGER;
DECLARE "iValidUser" INTEGER;
BEGIN
"iValidReceipt" := ( SELECT COUNT("ReceiptID") FROM "Users"."ExpenseReceipt" WHERE "ReceiptID" = "vReceiptID" );
"iValidUser" := ( SELECT COUNT("AccountID") FROM "Users"."Account" WHERE "CurrentToken" = "vCurrentToken" LIMIT 1 );
IF "iValidUser" = 0 THEN
RAISE 'Error' USING ERRCODE = '10001';
END IF;
IF "iValidReceipt" > 0 THEN
UPDATE "Users"."ExpenseReceipt" SET
"Total" = COALESCE( "vTotal" , "Total" )
, "TaxPercent" = COALESCE( "vTaxPercent" , "TaxPercent" )
, "ShippingCost" = COALESCE( "vShippingCost" , "ShippingCost" )
, "Reference" = COALESCE( CAST( "vReference" AS VARCHAR ) , "Reference" )
, "ReceiptDate" = COALESCE( "vReceiptDate" , "ReceiptDate" )
, "EditDate" = current_timestamp at time zone 'utc'
WHERE "ReceiptID" = "vReceiptID";
RETURN QUERY
SELECT
"ReceiptID"
, "Total"
, "TaxPercent"
, "ShippingCost"
, "Reference"
, "ReceiptDate"
FROM "Users"."ExpenseReceipt"
WHERE "ReceiptID" = "vReceiptID";
ELSE
RAISE 'Error' USING ERRCODE = '10101';
END IF;
END; $$
--I'll include the table itself in case its relevant
CREATE TABLE "Users"."ExpenseReceipt"
(
"ReceiptID" UUID NOT NULL DEFAULT uuid_generate_v4(),
"AccountID" UUID NOT NULL ,
"Total" DOUBLE PRECISION NOT NULL ,
"TaxPercent" DOUBLE PRECISION DEFAULT 0.0 ,
"ShippingCost" DOUBLE PRECISION DEFAULT 0.0 ,
"Reference" VARCHAR(96) ,
"ReceiptDate" TIMESTAMP ,
"EditDate" TIMESTAMP DEFAULT ( current_timestamp at time zone 'utc' )
);
Easy update function, uses coalesce to not update the value if the API call doesn't set them. Everything works fine (after dealing through the numerous naming issues I've run into with postgres, and there I think NpgSQL is relevant). I know how to get it right. I made a second one, basically exactly the same:
CREATE OR REPLACE FUNCTION "Api"."UpdateSupplyItem" ( "vItemID" UUID , "vDescription" VARCHAR , "vSize" VARCHAR , "vNetCost" DOUBLE PRECISION , "vPackageQuantity" DOUBLE PRECISION , "vNetWeight" DOUBLE PRECISION , "vCurrentToken" UUID )
RETURNS TABLE ( "ItemID" UUID , "Description" VARCHAR , "Size" VARCHAR , "NetCost" DOUBLE PRECISION , "PackageQuantity" DOUBLE PRECISION , "NetWeight" DOUBLE PRECISION )
LANGUAGE PLPGSQL
AS $$
DECLARE "iValidItem" INTEGER;
DECLARE "iValidUser" INTEGER;
BEGIN
"iValidItem" := ( SELECT COUNT(usi."ItemID") FROM "Users"."SupplyItem" usi WHERE usi."ItemID" = "vItemID" );
"iValidUser" := ( SELECT COUNT("AccountID") FROM "Users"."Account" WHERE "CurrentToken" = "vCurrentToken" LIMIT 1 );
IF "iValidUser" = 0 THEN
RAISE 'Error' USING ERRCODE = '10001';
END IF;
IF "iValidItem" > 0 THEN
UPDATE "Users"."SupplyItem"
SET
"Description" = COALESCE( "vDescription" , "Users"."SupplyItem"."Description" )
, "Size" = COALESCE( "vSize" , "Users"."SupplyItem"."Size" )
, "NetCost" = COALESCE( "vNetCost" , "Users"."SupplyItem"."NetCost" )
, "PackageQuantity" = COALESCE( "vPackageQuantity" , "Users"."SupplyItem"."PackageQuantity")
, "NetWeight" = COALESCE( "vNetWeight" , "Users"."SupplyItem"."NetWeight" )
WHERE "Users"."SupplyItem"."ItemID" = "vItemID";
RETURN QUERY SELECT usi."ItemID" , usi."Description" , usi."Size" , usi."NetCost" , usi."PackageQuantity" , usi."NetWeight" FROM "Users"."SupplyItem" usi WHERE usi."ItemID" = "vItemID" LIMIT 1;
ELSE
RAISE 'Error' USING ERRCODE = '10401';
END IF;
END; $$
--Again, the table in case it helps
CREATE TABLE "Users"."SupplyItem"
(
"ItemID" UUID NOT NULL DEFAULT uuid_generate_v4() ,
"AccountID" UUID NOT NULL ,
"Description" VARCHAR ,
"Size" VARCHAR ,
"NetCost" DOUBLE PRECISION ,
"PackageQuantity" DOUBLE PRECISION ,
"NetWeight" DOUBLE PRECISION
);
but it's quite different. You can see clearly that I've had to fully qualify the right hand side of every equals (where the earlier function had no need). I get ambiguity all the way down the update statement. It starts at ItemID, then Description, then Size... every attribute I think. First thing I did was alias the table
UPDATE usi [...] FROM "Users"."SupplyItem" usi
but that failed because you can't do short aliasing in an UPDATE in PG (relation usi."[...]" does not exist") which actually kind of sucks. I only figured out that it needed to be fully qualified when someone asked a similar question and the answer was "It must be a quirk of RETURNS TABLE."
So why is my second update "a quirk" but my first update works perfectly? I've had a tough time with PG (and I'm not a slouch), but having two functions that seem identical having entirely different results (at runtime no less) makes me uncomfortable. I'm posting here because I know the two functions must be markedly different; 99.9% of the time, there is no such thing as a "quirk." There is something I need to understand to work around to avoid in the future. What is the "gotcha" that I've missed in the second UPDATE function?
The problem is that you have a function variable "Size" (an OUT parameter defined in the RETURNS TABLE clause) and a column "Size" in "Users"."SupplyItem". So you have to qualify the reference to indicate what you mean.
I recommend using an alias for simplicity:
UPDATE "Users"."SupplyItem" AS si
SET "Size" = COALESCE("vSize" , si."Size")
...
There is no such ambiguity in your first example, because you didn't double quote the parameter TaxPercent, so it gets case folded to taxpercent and is different from the column "TaxPercent".

why my symmetric difference is not true?

i want to calculate symmetric difference between two set V(i,ip) and v(ipp,ippp)
i have set i={1,3,4,6} and j={1,2,..,10}
i have set T(i,j) and , 3 set V,W,b too , that
T(1)={2,5,10}
T (3)={7,10}
T (4)={2,5,6}
T (6)={2,5}
and V is union of T(i) , W is symmetric difference between T and V , and b is a difference between V(i,ip)
the result of my b is not true! why ?
how can i get difference between V(i,ip)?
v(i,ip)=t(i,j)+t(ip,j)
w(i,ip,ipp)= (t(i,j)+v(ip,ipp,j))-(t(i,j)*v(ip,ipp,j));
b(i,ip,ipp,ippp)=((v(i,ip,j)+v(ipp,ippp,j))-(v(ip,ipp,j)*v(ipp,ippp,j))) ;
*---- index and sets----*
sets
i /1,3,4,6/
j/1*10/
t(i,j) /
1.(2,5,10)
3.(7,10)
4.(2,5,6)
6.(2,5)
/ ;
alias(i,ip,ipp,ippp);
*---- parameter----*
parameter
MyOrd(i,ip);
*-------------------------------
MyOrd(i,ip)=i.val+(ip.val -1)*4;
set
v(i,ip,j)'for union only'
b(i,ip,ipp,ippp,j) 'symmetric diffrence between v and v'
w(i,ip,ipp,j) 'symmetric diffrence between t and v'
;
v(i,ip,j)$(i.val<ip.val)=t(i,j)+t(ip,j);
w(i,ip,ipp,j)$(ip.val<ipp.val) =(t(i,j)+v(ip,ipp,j))-(t(i,j)*v(ip,ipp,j));
b(i,ip,ipp,ippp,j)$(i.val<ip.val and ipp.val<ippp.val and MyOrd(i,ip)
display t,v,w,b;
in your code you write
MyOrd(i,ip)=i.val+(ip.val -1)*4;
try with
parameter
MyOrd(i,i1);
scalar
counter /1/
;
loop((i,i1)$(vulnerable(i) and vulnerable(i1) and i.val <i1.val ),
MyOrd(i,i1)=counter;
counter=counter+1;
);

Error 'failed to find conversion function from unknown to text' in sql query

I need to write a query to which if I pass some list of strings then it will check in particular table if those are present and return which are not present. I have written following query for that
SELECT temp_table.configuration_key FROM (#PLACEHOLDER) temp_table
LEFT JOIN configuration c ON (c.configuration_key = temp_table.configuration_key) WHERE c.configuration_key IS NULL;
where #PLACEHOLDER will be formed dynamically like following
1 . if single string is passed #PLACEHOLDER will be
SELECT 'xyz' configuration_key
if more than one string is passed #PLACEHOLDER will be
SELECT 'xyz' configuration_key UNION ALL SELECT 'abc'
and so on.
Here 2nd query works fine but gives following error to 1st query
failed to find conversion function from unknown to text
configuration table has single column named configuration_key
Can anyone tell me whats wrong here. how to form query if there is only one string passed (i.e form a table with single element). I know I can do it by entire different query. But cant I do this using same type of query?
I ran into a similar error trying to do an in-DB_Write of just one record into the database (Failed to find conversion function from unknown to character-varying). My in-DB_Write tool gets its input directly from an in-DB_Connect tool with a custom query. I'm using the Redshift Bulk load driver for my writes (I don't see a way to configure a specific in-DB_Write tool to use the regular driver). The bulk load driver uses the COPY command to load from S3.
After reading your post, I suspected that the in-DB_Write tool is assuming the first row is a header row and that actual data starts from the 2nd row. So I did a union of the exact same SQL in my in-DB_Connect and it worked.
In summary, this fails:
Select Coalesce(Max(etl_process_control.process_id), 0) + 1 as process_id
, 1 as job_id
, getdate() as process_start_dttm
, to_timestamp('1899-12-31 00:00:00','YYYY-MM-DD HH24:MI:SS') as process_end_dttm
, 'I' as process_status_cd
, 'In-Progress' as process_status_desc
, null as process_error_rsn
, -999 as rows_updated
, -999 as rows_inserted
, -999 as rows_deleted
, -999 as rows_failed
From etl_process_control
But this works:
Select Coalesce(Max(etl_process_control.process_id), 0) + 1 as process_id
, 1 as job_id
, getdate() as process_start_dttm
, to_timestamp('1899-12-31 00:00:00','YYYY-MM-DD HH24:MI:SS') as process_end_dttm
, 'I' as process_status_cd
, 'In-Progress' as process_status_desc
, null as process_error_rsn
, -999 as rows_updated
, -999 as rows_inserted
, -999 as rows_deleted
, -999 as rows_failed
From etl_process_control
union
Select Coalesce(Max(etl_process_control.process_id), 0) + 1 as process_id
, 1 as job_id
, getdate() as process_start_dttm
, to_timestamp('1899-12-31 00:00:00','YYYY-MM-DD HH24:MI:SS') as process_end_dttm
, 'I' as process_status_cd
, 'In-Progress' as process_status_desc
, null as process_error_rsn
, -999 as rows_updated
, -999 as rows_inserted
, -999 as rows_deleted
, -999 as rows_failed
From etl_process_control
Lastly, you'll notice that I'm not using a union ALL, so the above query essentially returns only one row.... but somehow it works. This is not an ideal solution but gets around the error.
I am not sure why this error is occurring with a single row subquery, but you can use explicit typecasting like
SELECT temp_table.configuration_key
FROM (SELECT 'xyz'::text configuration_key
) temp_table
LEFT JOIN configuration c ON (c.configuration_key = temp_table.configuration_key)
WHERE c.configuration_key IS NULL;
SQL Fiddle

Use SAS macro variable to create variable name in PROC SQL

I'm trying to create a set of flags based off of a column of character strings in a data set. The string has thousands of unique values, but I want to create flags for only a small subset (say 10). I'd like to use a SAS macro variable to do this. I've tried many different approaches, none of which have worked. Here is the code that seems simplest and most logical to me, although it's still not working:
%let Px1='12345';
PROC SQL;
CREATE TABLE CLAIM1 AS
SELECT
b.MEMBERID
, b.ENROL_MN
, CASE WHEN (a.PROCEDURE = &Px1.) THEN 1 ELSE 0 END AS CPT_+&Px1.
, a.DX1
, a.DX2
, a.DX3
, a.DX4
FROM ENROLLMENT as b
left join CLAIMS as a
on a.MEMBERID = b.MEMBERID;
QUIT;
Obviously there is only one flag in this code, but once I figure it out the idea is that I would add additional macro variables and flags. Here is the error message I get:
8048 , CASE WHEN (PROCEDURE= &Px1.) THEN 1 ELSE 0 END AS CPT_+&Px1.
-
78
ERROR 78-322: Expecting a ','.
It seems that the cause of the problem is related to combining the string CPT_ with the macro variable. As I mentioned, I've tried several approaches to addressing this, but none have worked.
Thanks in advance for your help.
Something like this normally requires dynamic sql (although I am not sure how will that works with SAS, I believe it may depend on how you have established connection with the database).
Proc sql;
DECLARE #px1 varchar(20) = '12345'
,#sql varhcar(max) =
'SELECT b.MEMBERID
, b.ENROL_MN
, CASE WHEN (a.PROCEDURE = ' + #Px1 + ') THEN 1 ELSE 0
END AS CPT_' + #px1 + '
, a.DX1
, a.DX2
, a.DX3
, a.DX4
FROM ENROLLMENT as b
left join CLAIMS as a
on a.MEMBERID = b.MEMBERID'
EXEC sp_excutesql #sql;
QUIT;
Your issue here is the quotes in the macro variable.
%let Px1='12345';
So now SAS is seeing this:
... THEN 1 ELSE 0 END AS CPT_+'12345'
That's not remotely legal! You need to remove the '.
%let Px1 = 12345;
Then add back on at the right spot.
CASE WHEN a.procedure = "&px1." THEN 1 ELSE 0 END AS CPT_&px1.
Note " not ' as that lets the macro variable resolve.
If you have a list it might help to put the list into a table. Then you can use SAS code to generate the code to make the flag variables instead of macro code.
Say a table with PX code variable.
data pxlist;
input px $10. ;
cards;
12345
4567
;
You could then use PROC SQL query to generate code to make the flag variable into a macro variable.
proc sql noprint;
select catx(' ','PROCEDURE=',quote(trim(px)),'as',cats('CPT_',px))
into :flags separated by ','
from pxlist
;
%put &=flags;
quit;
Code looks like
PROCEDURE= "12345" as CPT_12345,PROCEDURE= "4567" as CPT_4567
So if we make some dummy data.
data enrollment ;
length memberid $8 enrol_mn $6 ;
input memberid enrol_nm;
cards;
1 201612
;
data claims;
length memberid $8 procedure $10 dx1-dx4 $10 ;
input memberid--dx4 ;
cards;
1 12345 1 2 . . .
1 345 1 2 3 . .
;
We can then combine the two tables and create the flag variables.
proc sql noprint;
create table want as
select *,&flags
from ENROLLMENT
natural join CLAIMS
;
quit;
Results
memberid procedure dx1 dx2 dx3 dx4 enrol_mn CPT_12345 CPT_4567
1 12345 1 2 201612 1 0
1 345 1 2 3 201612 0 0

INSERT INTO SELECT,copy value+ 'string'

I need to copy a row .Copied row,I need to change value, this value + 'copy'
I made this sql..but it's not work..
INSERT INTO prizes_i18n (
lang_id
, translation_name
, translation_desc
, name
, lang_path)
SELECT prizes_s.lang_id
, prizes_s.translation_name + 'copy'
, prizes_s.translation_desc
, prizes_s.name
, prizes_s.lang_path
FROM prizes_i18n prizes_s
WHERE prizes_s.lang_id = 637;
Without + 'copy' its works.
Like this prizes_s.translation_name + 'copyy',but it's not work.
From this previous question you use MySQL? If so use concat for string concatenation.
SELECT 'foo' + 'bar' ...
Returns 0 in MySQL which would explain the error about doubles you are seeing.
INSERT INTO prizes_i18n (lang_id, translation_name, translation_desc,
name, lang_path)
SELECT prizes_s.lang_id,
concat(prizes_s.translation_name, 'copy'),
prizes_s.translation_desc, prizes_s.name, prizes_s.lang_path
FROM prizes_i18n prizes_s WHERE prizes_s.lang_id = 637;
Random guess...
prizes_s.translation_name + ' Copy' is too long for translation_name and you get string or binary data would be truncated error?
Is it SQL Server too? Is translation_name char or varchar?
INSERT INTO
prizes_i18n
(lang_id,translation_name,translation_desc,name,lang_path)
SELECT
prizes_s.lang_id
, concat(prizes_s.translation_name,'copy')
, prizes_s.translation_desc
, prizes_s.name
, prizes_s.lang_path
FROM
prizes_s WHERE prizes_s.lang_id = 637;
Also I think, that in your FROM clause the table prizes_i18n is unnecessary.