Selecting multiple fields in subquery - abap

This ABAP code works:
select *
into table <sub_result>
from ADRC
WHERE ADDRNUMBER
in ( select ADRNRA from AUFK where (cond_string) ).
But this does not:
select *
into table <sub_result>
from ADRC
WHERE (ADDRNUMBER, MANDT)
in ( select ADRNRA, MANDT from AUFK where (cond_string) ).
AFAIK the tuple syntax (ADDRNUMBER, MANDT) is valid for SQL. Is this not valid in Open SQL of ABAP?
If the tuple syntax is not allowed, what could I do?
P.S. In Open SQL checking for MANDT is not needed, so this is only sample query.

You can not use in for multiple columns. Try like this:
SELECT *
INTO table <sub_result>
FROM ADRC d
WHERE exists ( select 1 from AUFK a where a~ADDRNUMBER = d~ADDRNUMBER and a~MANDT = d~MANDT)

To complete Pelin's answer, here are two possible syntaxes, depending on the ABAP version :
DATA sflights TYPE TABLE OF sflight.
" Strict mode of OpenSQL (>= 7.40 SP 5 ; more syntaxes than old OpenSQL syntax)
SELECT * FROM sflight AS f INTO TABLE #sflights " <== # activates the strict mode
WHERE NOT EXISTS ( SELECT 1 FROM sbook AS b " <== 1 is possible in strict mode
WHERE b~carrid = f~carrid
AND b~connid = f~connid
AND b~fldate = f~fldate ).
" "Loose" mode of OpenSQL (strict mode not used)
SELECT * FROM sflight AS f INTO TABLE sflights " <== no # i.e. strict mode deactivated
WHERE NOT EXISTS ( SELECT * FROM sbook AS b " <== 1 is not possible
WHERE b~carrid = f~carrid
AND b~connid = f~connid
AND b~fldate = f~fldate ).

Related

How to make LIKE behave case-insensitive?

I have an importedParameter which I want to search inside of a column in a SELECT.
But for now it is case-sensitive, how can I make it case-insensitive ?
I've tried multiple things: AND LOWER(columnName) LIKE LOWER(#lv_string) or AND columnName LIKE #tst_string COLLATE utf8_general_ci and some other stuff but got this error:
A Boolean expression is required in positions starting with LOWER(Q.
Sample code:
DATA(tst_string) = '%' && importedParamter && '%'.
IF anotherParameter IS NOT INITIAL.
IF importedParamter IS NOT INITIAL.
SELECT * FROM <table1> as p
INNER JOIN <table2> as q on q~column1 = p~column1
WHERE p~column2 = #anotherParameter
AND q~column2 LIKE #tst_string
INTO CORRESPONDING FIELDS OF TABLE #anotherName
ENDIF.
ENDIF.
I believe Regex is your preferred choice: LIKE_REGEXPR:
SELECT *
FROM <table1> as p
INNER JOIN <table2> as q on q~column1 = p~column1
WHERE p~column2 = #anotherParameter
AND like_regexpr( pcre = '\bparam\b', value = q~column2, CASE_SENSITIVE = 'X' ) = '1'
INTO TABLE DATA(#anotherName).
It has CASE_SENSITIVE predicate which respects (or not) the case.
Though this is available only since ABAP 7.55, so on lower releases you are out of the luck.
This code works fine for me:
SELECT *
FROM adrp
WHERE LOWER( name_first ) LIKE 'phi%'
INTO TABLE #DATA(results).
It finds my personal data entry (as well as those of another "Philipp" and of a "Philip"), even though we are all spelled with a capital P.
LIKE LOWER( 'Phi%' ) does not work, but when you can't control the input, then you can convert it to lower case before the select:
DATA(tst_string) = 'Phi%'.
TRANSLATE tst_string TO LOWER CASE.
SELECT *
FROM adrp
WHERE LOWER( name_first ) LIKE #tst_string
INTO TABLE #DATA(results).
Release: 7.54
I am not sure which release specifically allowed functions like LOWER within the WHERE clause. According to the comments, it should work since 7.51.

Writing results of SQL query to Temp View in Databricks

I would like to create a Temporary View from the results of a SQL Query - which sounds like a basic thing to do, but I just couldn't make it work and don't understand what is wrong.
This is my SQL query - which works fine and returns Col1.
%sql
SELECT
Col1
FROM
Table1
WHERE EXISTS (
select *
from TempView1)
I would like to write the results in another table which I can query. Therefore I do this :
df = spark.sql("""
SELECT
Col1
FROM
Table1
WHERE EXISTS (
select *
from TempView1)""")
OK
df
Out[28]: DataFrame[Col1: bigint]
df.createOrReplaceTempView("df_tmp_view")
OK
%sql
select * from df_tmp_view
Error in SQL statement: AnalysisException: Table or view not found: df_tmp_view; line 1 pos 14;
'Project [*]
+- 'UnresolvedRelation [df_tmp_view], [], false
display(affected_customers_tmp_view)
NameError: name 'df_tmp_view' is not defined
What am I doing wrong ?
I don't understand the error saying that the name is not defined although I define it just one command above. Also the SQL query is working and returning data...so what am I missing ?
Thanks !
you need to get the global context of the view, for example in your case:
global_temp_db = spark.conf.get("spark.sql.globalTempDatabase")
display(table(global_temp_db + "." + 'df_tmp_view'))
documentation
for example:
df_pd = pd.DataFrame(
{
'Name' : [231232,12312321,3213231],
}
)
df = spark.createDataFrame(df_pd)
df.createOrReplaceGlobalTempView('test_tmp_view')
global_temp_db = spark.conf.get("spark.sql.globalTempDatabase")
display(table(global_temp_db + "." + 'test_tmp_view'))

Tera Data: Missing/Invalid SQL statement'E(3810)

I have this simple merge statement but it failed when running.
Any advice is appreciated.
MERGE INTO HP.SampleAll as A
USING (
select ALIGNED
from HP.Sample2
) as B
ON (A.md_nbr = B.md_nbr)
WHEN MATCHED THEN UPDATE
SET ALIGNED = A.ALIGNED ;
Error 3810 says that Column does not exist.
md_nbr dont exist in your subquery B - as you don't select it.
Maybe a solution is:
MERGE INTO HP.SampleAll as A
USING (
select ALIGNED, md_nbr
from HP.Sample2
) as B
ON (A.md_nbr = B.md_nbr)
WHEN MATCHED THEN UPDATE
SET ALIGNED = A.ALIGNED ;
or just USING HP.Sample2 as B

Proper type for OpenSQL IN operand

I have function module which imports my_values
my_values is an custom internal table type of string.
This "my_values" variable contains for example: ["foo", "bar"]
I want to select all values from table Z_MYTAB where the column my_col is in my_values.
I tried this:
SELECT * FROM Z_MYTAB WHERE
my_col in #my_values INTO TABLE #DATA(my_rows).
But this fails with an error message:
table my_values has wrong row structure
(The message was translated to English. The original could be slightly different)
I could loop over my_values but I would like to avoid this.
How to do SQL IN with host variables which are internal tables?
Selection with IN is possible only with a range table.
Conversion of an internal table into a range table can be done like this:
DATA ltr_value TYPE RANGE OF string.
ltr_value = VALUE #( FOR <my_value> IN my_values
( sign = 'I'
option = 'EQ'
low = <my_value> )
).
IN openands could be of 2 types:
SELECT ... WHERE my_col IN ( value1, value2 , value3)
in this case no host expression can be used as right operand
SELECT ... WHERE my_col IN sel_tab[]
in this case sel_tab is a range like
So you could use the following:
DATA sel_tab type range of string.
sel_tab = value #( for ls in my_values ( sign = 'I' option = 'EQ' low = ls ) ).
SELECT * FROM Z_MYTAB WHERE
my_col in #sel_tab[] INTO TABLE #DATA(my_rows).
Best regards
User JozsefSzikszai pointed me to "SELECT FOR ALL ENTRIES".
I found this in the docs:
For an elementary row type, the pseudo component table_line must be specified for comp.
See: https://help.sap.com/doc/abapdocu_752_index_htm/7.52/en-US/abenwhere_logexp_itab.htm
IF my_values is initial.
exit.
endif.
SELECT * FROM Z_MYTAB
FOR ALL ENTRIES IN #my_values WHERE
column_name = #my_values-table_line
INTO TABLE #DATA(result_rows).

Trying relational division on oracle (right parenthesis missing?)

I'm trying to execute the following query in Oracle:
SELECT c.id_cliente, c.nombre_cliente, c.apellidos_cliente
FROM cliente c
WHERE not exists (SELECT f.id_finca
FROM finca f
WHERE f.habitaciones = 3
EXCEPT
SELECT v.id_fincas
FROM visitas v
WHERE v.id_cliente = c.id_cliente)
But I am getting the error "missing right parenthesis".
The parenthesis are well-balanced, how can I solve this error?
Use MINUS instead of EXCEPT.
SELECT c.id_cliente,
c.nombre_cliente,
c.apellidos_cliente
FROM cliente c
WHERE NOT EXISTS (SELECT f.id_finca
FROM finca f
WHERE f.habitaciones = 3
MINUS
SELECT v.id_fincas
FROM visitas v
WHERE v.id_cliente = c.id_cliente)
there is no operator EXCEPT in Oracle. Use MINUS instead of it.
Additionally, your query seems weird: better try to make it with two not exists, I think it can give some performance.