sql select statement with field having multiple values - abap

I have few check-boxes on my selection screen. Each check-box corresponds to a value which a field of a table can take. I have to then fire a select query where a particular field of a table can have all values whose corresponding check-box is selected.
Suppose I have 5 check-box corresponding to values a1-a5.
Now if check-boxes 1, 3, and 4 are checked then the field of the table can have values a1 or a3 or a4.
select * from table where field = a1 or field = a2 or field = a3.
One way to do this is creating 5 variables and then doing something like this
if checkbox1 checked
then var1 = a1
else
var1 = '0' //something which would never occur in the field of the table
and so on for all check-boxes.
And then
select * from table where field = var1 or field = var2 or field = var3 or field = var4 or field = var5.
This becomes difficult if there are 15 check-boxes.
Is there a better way to do this?

Use a select-option/range table for this:
DATA field_range TYPE RANGE OF data_type_of_table_field.
IF p_check1 = abap_true.
field_range = VALUE #( BASE field_range ( sign = 'I' option = 'EQ' low = 'A1' ) ).
ENDIF.
IF p_check2 = abap_true.
field_range = VALUE #( BASE field_range ( sign = 'I' option = 'EQ' low = 'A2' ) ).
ENDIF.
" ...
SELECT whatever FROM wherever WHERE field IN field_range.
CAUTION: An empty range table will match anything ("no restrictions") and fetch the entire contents of the database table, so you'll usually need to check for this separately.

Try like this
select * from table where field IN (a1,a2,a3 ...)

one possible way: append checked values to an internal table and then use FOR ALL ENTRIES in select statement.

Related

How to update all the rows in a specific column in SQLITE3?

CREATE TABLE example (
id integer,
name text
);
SELECT COUNT(*) FROM example;
>> 10
SELECT * FROM example;
...>
id name
-- --------
1
2
3
4
5
6
7
8
9
10
if there is a table like the code-block over, and no values in the column "name" as you can see.
I want to update all the values of the column like (A, B, C, D, E, F, G, H, I, J)
But, it is so inefficient to write this codes.
UPDATE example SET name = "A" where id = 1,
UPDATE example SET name = "B" where id = 2,
.
.
.
UPDATE example SET name = "J" where id = 10,
Is there some way to run these codes in a code like loop or something?
We can use the CHAR() ASCII function here:
UPDATE example
SET name = CHAR(64 + id);
Note that 65 is the ASCII character code for A. Once your id column exceeds the number of uppercase alphabets, my answer will start assigning characters which are not uppercase letters. But your question also does not mention what the additional behavior should be.

How can I rename a value from one column based on a condition and keep any other values otherwise?

Using SQL, How can I rename a value from one column based on a condition and keep any other values otherwise?
I've tried:
select a, b,
case when a = 'specific value' then 'new_value'
else a -- keep the current value for anything else
end as c
from x;
ERROR: invalid input value for enum 'new_value'
is not about update columns on database, only select statement returned
select a, b,
case when a = 'specific value' then cast('new_value' as text)
else cast(a as text) -- keep the current value for anything else
end as c
from x;

How to do a search with multiple non-obligatory Input fields?

I would like to ask how to do a basic search filtering in a selection screen that has multiple input fields which aren't required.
I tried to do it by using multiple IF statements followed by WHERE clauses which solves my current problem but its not fully correct, if i work with only a few inputs (2 at the moment, 'ID' and 'Number'), the code isn't too long, but if its over 10 or so it feel wrong to do it this way
What i tried so far was approximately like this :
IF lv_id IS INITIAL and lv_nr IS INITIAL.
SELECT * from DBase INTO TABLE Local_Table.
ELSEIF lv_id IS NOT INITIAL AND lv_nr IS INITIAL.
SELECT * from DBase INTO TABLE Local_Table WHERE ID = lv_nr.
ELSEIF lv_id IS INITIAL AND lv_nr IS NOT INITIAL.
SELECT * from DBase INTO TABLE Local_Table WHERE Number = lv_nr.
ELSEIF lv_id IS NOT INITIAL AND lv_nr IS NOT INITIAL.
SELECT * from DBase INTO TABLE Local_Table WHERE ID = lv_id AND Number = lv_nr.
The expected result is for the search to get executed correctly by having no input or multiple non-obligatory inputs, without having to write a very long code in case the number of inputs is high.
you can use the IN Operator in your WHERE clause when you have multiple conditions.
First You need to define a Selection Table for every parameter and have to fill them or leave them empty.
types: begin of myselopt ,
sign type char1 ,
option type char2 ,
low type ... (depends on the type you want select)
high type ... ,
end of myselopt .
types : t_selopt type table of myselopt .
data: gt_selopt type t_selopt ,
gt_selopt_2 type t_selopt_2 . #needs to be defined first
if lv_id is not initial .
insert value #( sign = 'I' option = 'EQ' low = lv_id ) into table gt_selopt .
endif .
if lv_nr is not initial .
insert value #( sign = 'I' option = 'EQ' low = lv_nr ) into table gt_selopt_2 .
endif .
You have to do this for every Parameter you want to query. And your query would look like this
select * from dbaste into table local_table where id in gt_selopt
and number in gt_selopt_2 .
You can define your input fields as SELECT-OPTIONS (with optional NO INTERVALS NO-EXTENSION to mimick the look of PARAMETERS). Then just use the IN operator in your WHERE clause:
REPORT.
DATA: your_ztable TYPE your_ztable.
SELECT-OPTIONS: s_id FOR your_ztable-id NO INTERVALS NO-EXTENSION,
s_nr FOR your_ztable-number NO INTERVALS NO-EXTENSION.
AT SELECTION-SCREEN.
SELECT * FROM your_ztable
WHERE id IN #s_id
AND number IN #s_nr
INTO TABLE #DATA(local_table).
What about this approach with concatenated where conditions?
DATA:
lv_where TYPE string.
IF lv_id IS NOT INITIAL.
CONCATENATE ' AND ID' space '=' space '"' lv_id '"' INTO lv_where.
ENDIF.
IF lv_nr IS NOT INITIAL.
CONCATENATE ' AND Number' space '=' space '"' lv_nr '"' INTO lv_where.
ENDIF.
IF lv_where IS NOT INITIAL.
SHIFT lv_where By 5 PLACES. " to remove leading _AND_ (
ENDIF.
SELECT * from DBase INTO TABLE Local_Table WHERE (lv_where).

Negate a bind variable

I am using APEX 5.0 and I have a query such as:
Select * FROM table where condition = :BIND_VARIABLE
I have a list which dynamically fills in the bind variable. The list has two values which the bind variable can take:
Value 1
Everything except value 1
'Everything else' value which is returned is user controlled so I can't have an EXISTS or IN because I do not know all the values that will be in there.
Is it possible to do something like
Select * FROM table where condition = !'Value 1'
I don't remember exact syntax for oracle substring, but you can try something like:
Select *
FROM table
where
(condition = :BIND_VARIABLE AND SUBSTR(:BIND_VARIABLE, 1, 1) <> '!')
OR
(condition <> SUBSTR(:BIND_VARIABLE, 2) AND SUBSTR(:BIND_VARIABLE, 1, 1) = '!')
so, if your value starts with ! symbol - you will look for all except passed value

DB2 Increment a value by a certain amount

I need to write a query that increments a value in a table by 3 when run.
I would like to do something like this but this doesn't work.
UPDATE table
SET value = (SELECT value
FROM table
WHERE condition = true) + 3
WHERE condition = true
As in the title this is a DB2 database, any ideas?
EDIT: Actually this does work, could also do the + 3 in the select. I just had some stuff in the wrong place with the casting I had to do
Thanks in advance
I think what you are looking for is simply
UPDATE table SET value = value + 3 WHERE condition = TRUE
Does that work?
If you want all rows where condition = true to have (for example) 3+ the max value of any row for which the condition is true, use this:
UPDATE table SET value =
(
SELECT MAX(value)
FROM table WHERE condition = true
) + 3
WHERE condition = true