Behavior of IN with empty subquery - abap

I want to select every customer from the table KNA1 which does not have any entry in table KNBK.
So I made a select query which should do this for me:
SELECT-OPTIONS: s_kn_nr FOR kna1-kunnr.
SELECT-OPTIONS: s_kn_okd FOR kna1-ktokd.
SELECT * FROM kna1
INTO TABLE #DATA(ls_kna1)
WHERE kunnr IN #s_kn_nr
AND ktokd IN #s_kn_okd
and kunnr not in ( select kunnr from knbk where kunnr in #s_kr_nr )
Now my question is, does the select query handle empty subselects in the same way as empty select options and just select everything?

The answer is simple: no.
Such a subquery returns a set and IN functions here exactly as the mathematical operation of belonging to set or no. So if the set is empty then no element belongs to it.

Related

Select from where in ( ) table?

I want a select with dynamic where conditions in ABAP Syntax.
An SQL Statement would look like this:
SELECT * FROM MCH1 WHERE MATNR IN (...) AND CHARG IN (...)
My approach was to add 2 structures ZMATN_STR and ZCHARG_STR to the dictionary with associated components as line (MATNR, CHARG).
Then create 2 table types with associated line types.
Now im stucked in ABAP because I don't know how to write the where clause.
That's what I have so far:
SELECT *
FROM
mch1
FOR ALL ENTRIES IN #matnrs
WHERE
matnr = #matnrs-matnr
INTO TABLE #DATA(lt_result).
It works for either matnr or charg but not with both of them.
Additional Info
This select happens in a function module where 2 import parameter exists (the 2 table types) - so I cannot just write where in ('xxx', 'yyy')
data lr_matnr type range of matnr.
data lr_charg type range of MCH1-charg.
"Fill lr_matnr and lr_charg...
SELECT * FROM MCH1 WHERE MATNR IN #lr_matnr AND CHARG IN #lr_charg
INTO TABLE #data(lt_result).

How to achieve NOT EXISTS with the ABAP CDS?

I would like to select all EKPO records that don't have an existing posting in MSEG table.
In ABAP SQL this can be done like below:
SELECT ebeln, ebelp FROM ekpo INTO TABLE #DATA(orders)
WHERE NOT EXISTS ( SELECT ebeln FROM mseg
WHERE ebeln = ekpo~ebeln
AND ebelp = ekpo~ebelp ).
The only solution I found is to create 2 CDS views, the first one to select all the orders with a record in MSEG and the second one being the negation of the first. But I would expect a cleaner solution so I wanted to ask here.
Here's how we do it:
define view my_view as
select from ekpo
association[0..1] to mseg
on mseg.ebeln = ekpo.ebeln
and mseg.ebelp = ekpo.ebelp
{
ebeln,
ebelp
}
where mseg.mandt is null
If no entry matching the criteria exists in mseg, all fields of the association will be null. Otherwise, mseg.mandt will never be null.

ABAP LIKE with select option

I have the following abap program that looks as following:
TABLES lfa1.
DATA gt_lfa1 TYPE SORTED TABLE OF lfa1 WITH UNIQUE DEFAULT KEY.
SELECT-OPTIONS sl_lifnr FOR lfa1-lifnr.
SELECT-OPTIONS sl_name FOR lfa1-name1.
START-OF-SELECTION.
SELECT * FROM lfa1
INTO CORRESPONDING FIELDS OF TABLE gt_lfa1
WHERE lifnr IN sl_lifnr
AND name1 LIKE sl_name.
Searching for vendors that name starts with:
I've got no results, but it exists vendors with this pattern.
It's not necessary to use LIKE. You can use IN instead.
I ran your code with IN in the SQL and I have results in the table.
if you use a select option you have to use the statement IN not like:
s_matnr = *3578 *
select options s_matnr type mara-matnr.
select bismt
from mara
into lv_bismt
where matnr in s_matnr
If you use s/4hana you can use even fuzzy
You need to replace * with %, if you are using LIKE operand. https://help.sap.com/doc/abapdocu_750_index_htm/7.50/de-DE/abenwhere_logexp_like.htm
REPLACE ALL OCCURENCES OF '*' in sl_lifnr WITH '%'
REPLACE ALL OCCURENCES OF '*' in sl_name WITH '%'
SELECT * FROM lfa1
INTO CORRESPONDING FIELDS OF TABLE gt_lfa1
WHERE lifnr LIKE sl_lifnr
AND name1 LIKE sl_name.

SQL Query to match if data is not present in another table

I have two tables named tblStockManagement and tblFolding in my database. i have column Name in tblFolding table and column FoldingID as Foreign Key in tblStockManagement table. now i have comboBox in my Winform and i want Names of Items in combobox from tblFolding Table but only those items that are not in tblStockManagement Table.
(because i dont want to select data again if it is already in tblStockManagement table . instead i will update the quantity later).
these are the screenshots of both of tables. please tell me how can i do that
NOT EXISTS version:
select *
from tblFolding f
where not exists (select * from tblStockManagement SM
where sm.FoldingID = f.FoldingID)
NOT EXISTS is "NULL safe", which NOT IN isn't.
This is you need.Basically a sub query which gets all folding id and using not in operator I exclude those matching sets.
SELECT Name
FROM tblFolding
WHERE FoldingID NOT IN (
SELECT FoldingID
FROM tblStockManagement
)
;
You can use SQL NOT condition
Select Name
From tblFolding
Where FoldingId Not In (Select FoldingId From tblStockManagement)
Order By Name

Set column type with a select ... into statement

I'm trying to create a table using a SELECT ... INTO statement. The table is created and populates properly, but I want to change the data type of two of the columns.
SELECT DISTINCTROW
AR_Server_Pre.OrderID,
AR_Server_Pre.LineTotal,
AR_Server_Pre.[Total payments],
AR_Server_Pre.ShipDate,
(AR_Server_Pre.LineTotal-nz(AR_Server_Pre.[Total Payments])) AS AmountDue
INTO AR_Final
FROM AR_Server_Pre
WHERE
((([AR_Server_Pre].[LineTotal]-nz([AR_Server_Pre].[Total Payments]))>0.5)
AND
((AR_Server_Pre.ShipDate)<Date()));
I want to assign column type of currency to LineTotal and AmountDue. AR_Server_Pre is a Select Query, so the simple solution of "Change it at that table) won't work.
You can wrap the specified fields in a CCur() function to force them to be Currency, e.g.,
SELECT DISTINCTROW
AR_Server_Pre.OrderID,
CCur(AR_Server_Pre.LineTotal) AS LineTotal,
...