Fill range table from itab using LET - abap

I found this code for filling a range table (source is already offline):
DATA lr_vkorg TYPE RANGE OF vkorg.
TYPES: lr_range_t TYPE RANGE OF vkorg.
lr_vkorg = VALUE lr_range_t(
LET s = 'I'
o = 'EQ'
IN sign = s
option = o
( low = '1100' )
( low = '1200' )
( low = '1300' )
( low = '1400' )
( low = '1500' )
).
But instead of doing something like this:
( low = '1' )
( low = '2' )
...
I want to fill it with the values of an internal table ['1', '2', ...].
Does anyone have an idea how to do this?
Update: This is how I did it based on the answer:
DATA:
lt_itab TYPE TABLE OF string,
lt_range_itab TYPE RANGE OF string
.
APPEND '1' TO lt_itab.
APPEND '2' TO lt_itab.
APPEND '3' TO lt_itab.
APPEND '4' TO lt_itab.
lt_range_itab = VALUE #(
FOR <ls_itab> IN lt_itab
( sign = 'I'
option = 'EQ'
low = <ls_itab> )
).

You can declare macro utilizing your declared structures like this:
DEFINE range.
lr_vkorg = VALUE lr_range_t( BASE lr_vkorg ( sign = 'I' option = 'EQ' low = &1 ) ).
END-OF-DEFINITION.
And then fill your ranges with this one-liner:
range: '1100', '1200', '1300', '1400', '1500', '1600'.
If we speak about filling range from itab, use this statement:
lr_vkorg = VALUE #( FOR ls_vkorg IN gt_vkorg
( sign = 'I'
option = 'EQ'
low = ls_vkorg-vkorg )
).

lr_vkorg = VALUE # ( sign = 'I' option = 'EQ' ( low = '1100' ) ( low = '1200' )
( low = '1300' ) ( low = '1400' ) ( low = '1500' ) ).

Related

How to improve SQL query when conditions grows dynamically

Usecase:
User want to get Sum amount by grouping a certain number of column values. To restrict the number of rows the Where condition is provided with the columns with their respective values.
Query Description:
Below is the SQL query in which the columns are decided dynamically as per the user requirement and at the same time the Groupby columns are also decided by the user dynamically.
In the Where condition, the condition grows dynamically depending upon the user selection.
SQL Query
SELECT transactionLine.department,
transactionLine.class,
transactionLine.cseg1,
transactionLine.cseg_grant,
transactionLine.cseg_restriction,
transactionLine.cseg_revtype,
transactionLine.cseg_rev_sub,
transactionLine.cseg_timerestrict,
transactionLine.cseg_fun_exp,
transactionLine.cseg_region,
BUILTIN_RESULT.TYPE_FLOAT(SUM(((NVL(CASE
WHEN transaction.posting = 'T' THEN TO_NUMBER(transactionaccountingLine.amount)
END, 0) + NVL(CASE
WHEN transaction.recordType = 'purchaseorder' THEN TO_NUMBER(transactionaccountingLine.amount)
END, 0)) - NVL(CASE
WHEN ((transaction.recordType = 'vendorbill'
AND BUILTIN.DF(transactionLine.createdfrom) IS NOT NULL)
AND UPPER(BUILTIN.DF(transaction_0.status)) NOT LIKE '%CLOSED%')
AND UPPER(BUILTIN.DF(transaction_0.status)) NOT LIKE '%FULLY BILLED%' THEN TO_NUMBER(transactionaccountingLine.amount)
END, 0)) + NVL(CASE
WHEN (transaction.recordType = 'vendorbill'
AND transaction.posting = 'F')
AND BUILTIN.DF(transactionLine.createdfrom) IS NOT NULL THEN TO_NUMBER(transactionaccountingLine.amount)
END, 0))) AS SUMNVLCASEWHENposting
FROM TRANSACTION,
account,
transactionaccountingLine,
TRANSACTION transaction_0,
transactionLine
WHERE ((((transactionaccountingLine.account = account.id(+)
AND (transactionLine.transaction = transactionaccountingLine.transaction
AND transactionLine.id = transactionaccountingLine.transactionline))
AND transactionLine.createdfrom = transaction_0.id(+))
AND transaction.id = transactionLine.transaction))
AND ((transactionLine.department= '11'
AND transactionLine.cseg_grant ='1'
AND transactionLine.class = '12'
AND transactionLine.cseg_restriction = '1'
AND transactionLine.cseg_revtype = '1'
AND transactionLine.cseg1 = '4'
AND transactionLine.cseg_rev_sub = '1'
AND transactionLine.cseg_timerestrict = '1'
AND transactionLine.cseg_fun_exp = '4'
AND transactionLine.cseg_region = '1') OR (transactionLine.department= '12'
AND transactionLine.cseg_grant ='1'
AND transactionLine.class = '12'
AND transactionLine.cseg_restriction = '1'
AND transactionLine.cseg_revtype = '1'
AND transactionLine.cseg1 = '4'
AND transactionLine.cseg_rev_sub = '1'
AND transactionLine.cseg_timerestrict = '1'
AND transactionLine.cseg_fun_exp = '4'
AND transactionLine.cseg_region = '1'))
AND ((NVL(account.custrecord_bm_budgetaccount, 'F') = 'F'
AND (NOT(UPPER(transaction.status) IN ('PURCHORD:H', 'PURCHORD:G', 'PURCHORD:A', 'PURCHORD:P'))
OR UPPER(transaction.status) IS NULL)
AND UPPER(account.accttype) IN ('COGS',
'DEFEREXPENSE',
'EXPENSE',
'OTHEXPENSE')))
GROUP BY transactionLine.class,
transactionLine.department,
transactionLine.cseg_grant,
transactionLine.cseg_restriction,
transactionLine.cseg_revtype,
transactionLine.cseg1,
transactionLine.cseg_rev_sub,
transactionLine.cseg_timerestrict,
transactionLine.cseg_fun_exp,
transactionLine.cseg_region
Question:
Is there any performance impact if the query has more no of Group by
conditions?
Here in this example, the result return from the query is limited by having the below where conditions. This query can grow as user select different values for the respective column. By doing this way is there going to be any performance impact? Can this query be fine-tuned to improve the query performance?
((transactionLine.department= '11'
AND transactionLine.cseg_grant ='1'
AND transactionLine.class = '12'
AND transactionLine.cseg_restriction = '1'
AND transactionLine.cseg_revtype = '1'
AND transactionLine.cseg1 = '4'
AND transactionLine.cseg_rev_sub = '1'
AND transactionLine.cseg_timerestrict = '1'
AND transactionLine.cseg_fun_exp = '4'
AND transactionLine.cseg_region = '1') OR (transactionLine.department= '12'
AND transactionLine.cseg_grant ='1'
AND transactionLine.class = '12'
AND transactionLine.cseg_restriction = '1'
AND transactionLine.cseg_revtype = '1'
AND transactionLine.cseg1 = '4'
AND transactionLine.cseg_rev_sub = '1'
AND transactionLine.cseg_timerestrict = '1'
AND transactionLine.cseg_fun_exp = '4'
AND transactionLine.cseg_region = '1'))

Apply IF conditional at the end of the query

I'm new in sql server and I have WHERE clause like this:
WHERE[D].[IsLocked] = 0
AND(#StartDate IS NULL OR ISNULL([TA].[ModifiedDate], [TA].[CreationDate]) >= #StartDate)
AND(#EndDate IS NULL OR ISNULL([TA].[ModifiedDate], [TA].[CreationDate]) <= #EndDate)
AND((CASE WHEN[T].[TaskStatusId] = '09E02513-00AD-49E3-B442-A9ED2833FB25'
THEN 1 ELSE 0 END) = #Completed)
AND((#FilterEmpKey IS NULL AND[TA].[EmpKey] = #CurrentEmpKey)
OR (ISNULL([TA].[ModifiedAssignedBy], [TA].[AssignatedBy]) = #FilterEmpKey
AND[TA].[EmpKey] = #CurrentEmpKey))
But now I want to add if conditional in order to add more filters at the end of query like:
IF(#FilterEmpGuid IS NOT NULL)
AND[TA].[EmpKey] = #CurrentEmpKey
AND[TA].[AssignatedBy] = #CurrentEmpKey
AND[TA].[EmpKey] = #FilterEmpKey
But I get:
The multi-part identifier [TA].[EmpKey] could not be bound
What am I doing wrong?
IF conditionals are only for use outside sql queries, such as in procedures etc.
In a query itself you are limited to AND, OR and CASE statements, so you will need to rewrite your IF conditional for this:
AND (#FilterEmpGuid IS NULL
OR (
[TA].[EmpKey] = #CurrentEmpKey
AND[TA].[AssignatedBy] = #CurrentEmpKey
AND[TA].[EmpKey] = #FilterEmpKey
))
You could move the additional filter options into a scalar function.
If you know the additional fields that may be filtered, you may be able to get away with something like:
CREATE FUNCTION dbo.ExtendFilter(
#column_value VARCHAR(50), #param_value VARCHAR(50)
)
RETURNS BIT
AS
BEGIN
DECLARE #return BIT = 1; -- default RETURN to 1 ( include ).
IF ( NULLIF( #param_value, '' ) IS NOT NULL )
BEGIN
-- compare the column's value to the param value
IF ( #column_value <> #param_value )
SET #return = 0; -- don't include this record.
END
RETURN #return;
END
GO
And then use it like:
WHERE
{ other WHERE stuff }
AND dbo.ExtendFilter( [TA].[EmpKey], #CurrentEmpKey ) = 1
AND dbo.ExtendFilter( [TA].[AssignatedBy], #CurrentEmpKey ) = 1
AND dbo.ExtendFilter( [TA].[EmpKey], #FilterEmpKey ) = 1
Mind you this is just an example. You'd want to check #pram_value for NULL, etc...

How to use bitwise operator in existing sql query?

Here is my sql query. I have column name "ExpenseBucketCoverage" in claim table in which I am storing bitwise operators store multiple values in one column like below
MED_COPAY = 1, MED_DED= 10, MED_COINS = 100, RX_COPAY = 1, RX_DED= 10, RX_COINS = 100
I want to replace hard coded value like MED_COPAY, MED_COINS, MED_DED, RX_DED, RX_COINS & RX_COPAY in query by using ExpenseBucketCoverage column value. Can some one please tell me how can I do that?
Someone has suggested me below soultion
retrieve data from claim and left joining the first matched record in eligibility. And then add custom code to loop through the datarows to split the rows by covered expense bucket, and set the service category code in-memory column based on the ExpenseBucketCoverage value for the claim.
SELECT
e.categoryid,
c.servicetype,
'II' AS RepordType,
e.TPAId AS TPA_Id,
e.EmployerCode,
e.SubscriberId,
e.MemberID,
c.ServiceFrom,
c.ServiceTo,
CASE
WHEN e.categoryid IN( 'MED_DED', 'RX_DED' ) THEN
deductible
WHEN e.categoryid IN( 'MED_COINS', 'RX_COINS' ) THEN
isnull(coins,0)
WHEN e.categoryid IN( 'MED_COPAY', 'RX_COPAY' ) THEN
copay
ELSE 0
END AS ClaimAmount,
'' AS AccountTypeCode,
'1' ClaimsCrossoverAutoPay,
e.CategoryId,
CASE c.ServiceType
WHEN 'H' THEN
CASE e.PayeeIndicator
WHEN 'N' THEN '0'
WHEN 'Y' THEN '1'
END
WHEN 'P' THEN '0'
END AS PayProvider,
CASE c.ServiceType
WHEN 'H' THEN
CASE PayeeIndicator
WHEN 'N' THEN '0'
WHEN 'Y' THEN '1'
END
WHEN 'P' THEN '0'
END AS ReimbursementMethod,
CASE c.ServiceType
WHEN 'H' THEN c.Provider
WHEN 'P' THEN ''
END AS ProviderId,
'1' EnforceAccountEffectiveDates,
c.Id,
c.ClaimNumber + e.CategoryId as 'ExternalClaimNumber',
c.ProviderName,
c.CarrierId + ';' + c.SourceClaimNumber AS Notes
FROM Claim c
INNER JOIN Eligibility e ON e.TPAId = c.TPAId AND e.EIN = c.EIN AND
c.Processed = 'Y' AND e.FilterType = 'Eligibility'
AND c.TPAId='PrimePay'
AND (c.ServiceFrom >= e.BenefitEffectiveDate
AND c.ServiceFrom <=e.BenefitTermDate)
AND ( ( c.PayorID = c.PatientSSN
AND e.SubscriberSSN = c.PatientSSN
AND (c.EmployeeFirstName = c.PatientFirstName
AND c.EmployeeLastName = c.PatientLastName)
AND(e.MemberSSN = '' OR e.MemberSSN = NULL)
AND(e.MemberFirstName = '' OR e.MemberFirstName = NULL)
AND(e.MemberLastName = '' OR e.MemberLastName = NULL))
OR((c.PayorID != c.PatientSSN AND e.MemberSSN = c.PatientSSN
AND e.MemberFirstName = c.PatientFirstName
AND e.MemberLastName = c.PatientLastName)
OR(c.PayorID != c.PatientSSN AND e.MemberFirstName = c.PatientFirstName
AND e.MemberLastName= c.PatientLastName)))
AND (( c.Servicetype ='P'
AND e.CategoryID IN('RX_COINS','RX_COPAY', 'RX_DED' ))
OR ( c.Servicetype = 'H'
AND e.CategoryID IN( 'MED_COINS','MED_COPAY', 'MED_DED' )))

Unix Sql -- Updating One table from a 2nd table -- null value issue

I have been looking at the web for hours trying to determine what is wrong with my code. I keep receiving the ORA-01407: cannot update ("AMIOWN"."MEMBER"."LANGUAGE_X") to NULL. I need to update the language in the member table when the language in the contract table is not null. The 3rd table is required in order to drill down to specific members. Below is the code:
update member m
set language_x =
(select language_x
from contract c
where m.contract_nbr = c.contract_nbr and
c.language_x is not null and
m.member_nbr =
(select member_nbr
from member_span ms
where m.member_nbr = ms.member_nbr and
ms.void = ' ' and
ms.carrier = 'PM' and
ms.prog_nbr = 'GP' and
ms.region = 'TR' and
(ms.ymdeff <= 20160218 or ms.ymdeff > 20160218) and
ms.ymdend > 20160218
)
);
Some of the postings also suggested adding another line after the last parenthesis checking for:
where exists (select 1 from contract c where m.contract_nbr = c.contract_nbr and c.language_x is not null);
I am working in a unix environment, tables are contained in an amisys database.
Thank you for any suggestions.
you need to add the where condition to your update statement
update member m
set language_x = (select language_x
from contract c
where m.contract_nbr = c.contract_nbr
and c.language_x is not null
and m.member_nbr = (select member_nbr
from member_span ms
where m.member_nbr = ms.member_nbr
and ms.void = ' '
and ms.carrier = 'PM'
and ms.prog_nbr = 'GP'
and ms.region = 'TR'
and (ms.ymdeff <= 20160218 or ms.ymdeff > 20160218)
and ms.ymdend > 20160218)
)
where exists (select language_x
from contract c
where m.contract_nbr = c.contract_nbr
and c.language_x is not null
and m.member_nbr = (select member_nbr
from member_span ms
where m.member_nbr = ms.member_nbr
and ms.void = ' '
and ms.carrier = 'PM'
and ms.prog_nbr = 'GP'
and ms.region = 'TR'
and (ms.ymdeff <= 20160218 or ms.ymdeff > 20160218)
and ms.ymdend > 20160218)
);
Below is a more elegant solution, but depending on your datamodel it might or might not work
Update
(
select m.language_x as oldval
c.language_x as newval
from member m
,contract c
where m.contract_nbr = c.contract_nbr
and c.language_x is not null
and m.member_nbr = (select member_nbr
from member_span ms
where m.member_nbr = ms.member_nbr
and ms.void = ' '
and ms.carrier = 'PM'
and ms.prog_nbr = 'GP'
and ms.region = 'TR'
and (ms.ymdeff <= 20160218 or ms.ymdeff > 20160218)
and ms.ymdend > 20160218)
) t
set t.oldval =t.newval

Subquery returned more than 1 value. Update Select Minus

I have the following update scrpit..
UPDATE LIMRA_Retail_Current
SET AnnualizedWOExcessPremium = (SELECT
ISNULL(ul.AnnualizedWOExcessPremium, 0)-
isnull((select iul.AnnualizedWOExcessPremium
from dbo.LIMRA_Retail_Current iul
where ul.Distribution = iul.distribution
and ul.company = iul.company
and ul.Year = iul.year
and ul.Quarter = iul.quarter
and iul.Market = 'Retail'
and replace(ul.Product, 'Universal Life', 'Index Universal Life') = iul.product
),0) UL_MINUS_IUL
FROM dbo.LIMRA_Retail_Current UL
WHERE ul.Product like 'Universal Life%'
AND ul.Market = 'Retail')
How can I update the column AnnualizedWOExcessPremium using ALL the values of UL_MINUS_IUL. I want to use ALL the values in my update.
Looks like your sub select just needs a SUM:
(SELECT
SUM(ISNULL(ul.AnnualizedWOExcessPremium, 0)- isnull((select iul.AnnualizedWOExcessPremium )
from dbo.LIMRA_Retail_Current iul
where ul.Distribution = iul.distribution
and ul.company = iul.company
and ul.Year = iul.year
and ul.Quarter = iul.quarter
and iul.Market = 'Retail'
and replace(ul.Product, 'Universal Life', 'Index Universal Life') = iul.product
),0) UL_MINUS_IUL