Count duplicates in an internal table? - abap

I just want to ask on how to count duplicates in an internal table. I wanted to this in order for me to count per customer and put it into the Customer count column.
Sales Employee Customer Customer Count
a 1 2
a 2 2
b 3 3
b 2 3
b 4 3
c 1 1

as suncatcher mentions in his comment, using sql aggregates is more efficient than looping through internal tables. But if that is not possible in your case, one way would be to use the collect statement. collect adds entries to an internal table and adds up numerical fields when a row with the same key fields already exists. Create an internal table with a field for your sales employee, another field for the count and loop through your sales table, using collect to update your count table for each sale.
types: begin of t_count,
employee type text10,
count type i,
end of t_count.
data: it_count type standard table of t_count,
wa_count type t_count.
loop at it_sales into wa_sales.
move: wa_sales-employee to wa_count-employee,
1 to wa_count-count.
collect wa_count into it_count.
endloop.
The example assumes you have a table it_sales, a work area wa_sales, both with a field employee. Table it_count then contains a list of your employees (in the order they appear in your sales table) and the number of times they appeared in the sales table.

FIELD-SYMBOLS : <lfs_sales> TYPE ty_sales.
Assuming li_sales is an internal table with columns Sales_employee, Customer and customer_count. Initially the table entries are present as follows.
Sales_employee Customer customer_count
a 1 0
a 2 0
b 3 0
b 2 0
b 4 0
c 1 0
We need to calculate the duplicate sales_employee count and update the customer_count field. We can make use of collect statement as suggested by Dirik or make use of control break statements as shown below.
Prerequisite to make use of SUM keyword is to initialize the customer_count as 1 in each row so that it can sum up the customer count based on similar sales_employee.
LOOP AT li_sales ASSIGNING <lfs_sales>.
<lfs_sales>-customer_count = 1.
ENDLOOP.
Now the entries look as shown below.
Sales_employee Customer customer_count
a 1 1
a 2 1
b 3 1
b 2 1
b 4 1
c 1 1
Following code does update the customer_count field value.
LOOP AT li_sales INTO rec_sales.
AT END OF employee.
SUM.
MOVE-CORRESPONDING rec_sales TO rec_count.
APPEND rec_count TO li_count.
CLEAR rec_count.
ENDAT.
ENDLOOP.
SORT li_count BY employee.
LOOP AT li_sales ASSIGNING <lfs_sales>.
CLEAR rec_count.
READ TABLE li_count INTO rec_count
WITH KEY employee = <lfs_sales>-employee
BINARY SEARCH.
IF sy-subrc IS INITIAL.
<lfs_sales>-count = rec_count-count.
ENDIF.
ENDLOOP.
Now the internal table gets assigned with customer_count as below.
Sales_employee Customer customer_count
a 1 2
a 2 2
b 3 3
b 2 3
b 4 3
c 1 1

Related

Oracle SQL - Need to eliminate data if at least one of the particular condition is not satisfied

My question is related to Oracle sql. I have a two tables say, study table and another one is study part table. Stdyno is the primary key in study table and (stydyno + sqncno) is the primary key in studypart table.
EG: studypart table has data as below.
studyNo sqnc part approvalIN
--------------------------------
123 1 fgh Y
123 2 jhf N
123 3 rty N
456 1 wer N
456 2 wdg N
456 3 ghg N
I need query in such a way that my output from studypart table gives result
as study number which has all the approvalIn as N. If it has at least one of the approvalIn as 'Y'
then that studyno should be excluded from the result.
Desired output:
studyno: 456
I tried this implementation in stored procedure taking Y and N approvalIn count separately ie,
if a studyno has both the count then exclude it and
if it has only one count say either N or Y the include it.
But i would like to know how to achieve this is query.
You can do it by excluding those rows whose count of "approvalIN = 'N'" does not match the total count of "approvalIN" values.
SELECT STUDYNO
FROM tab
GROUP BY STUDYNO
HAVING SUM(CASE WHEN approvalIN = 'N' THEN 1 END) = COUNT(approvalIN)
Check the demo here.

R group by distinct pairs within a column and then count

I have a data frame containing two columns - ID and SHOP, and I want to find the count of unique Customer IDs that correspond to unique combination of shops in the Shop column. My original data frame is as follows
CustomerID
SHOP
1
A
2
A
3
B
1
C
2
D
4
E
The intended output should be as follows:
SHOP PAIR
CUSTOMERS
A-C
1
A-D
1
Is there a smart way to achieve this in R? Thanks for the help!

SQL - Update in a cross apply query

UPDATE Table1
SET SomeColumn = X.SomeOtherColumn
FROM Table1 T1
CROSS APPLY
(SELECT TOP 1 SomeOtherColumn
FROM Table2 T2
WHERE T2.SomeJoinColumn = T1.SomeJoinColumn
ORDER BY CounterColumn) AS X
I want to increase CounterColumn by 1 each time the cross apply query runs. Is there any way I could achieve this?
Some context and sample data
I have a table containing information about companies. I want to anonymize the company numbers in this table. To do this, I want to use data from another table, containing synthetized data. This table has a much smaller sample size. So I have to reuse the same synthetic companies multiple times. For each row in the table I anonymize, I want to pick a synthetic company of the same type. I want to use all the synthetic companies. That's where the counter comes in, counting how many times I've used that specific synthetic company. By sorting by this counter, I was hoping to be able to always pick the synthetic company that's been used the least.
Company table (Table1)
CompanyNumber
Type
67923
2
82034
2
90238
7
29378
2
92809
5
72890
2
Synthetic company table (Table2)
SyntheticCompanyNumber
Type
Counter
08366
5
0
12588
2
0
33823
2
0
27483
7
0
Expected output of Company table:
CompanyNumber
Type
12588
2
33823
2
27483
7
12588
2
08366
5
33823
2
Expected output of synthetic company table
SynteticCompanyNumber
Type
Counter
08366
5
1
12588
2
2
33823
2
2
27483
7
1

Create a new record based on multiple records

I have a table with Accounts that, if there are multiple matching ones, I need to combine to create a new one in a procedure.
The table looks like:
ACCT ID QTY LEI
A_1 2 200 NULL
A_2 3 200 NULL
A_3 3 200 0
A_1 3 100 NULL
BB_1 2 200 NULL
BB_2 2 100 NULL
BB_3 3 200 0
BB_1 3 100 NULL
What I am trying to do is:
Find the ones I need to combine based on ACCT; The data above basically has two ACCTS, A and BB, the "_" are just to identify them as individual sub accounts.
For column QTY: SUM of QTY based on the ID and ACCT
For column LEI: If any record in the group of ACCT and ID is 0 and rest are NULL then replace with 0, if all are NULL then NULL
If there's only one record (no other record to merge with), that whole line will be used (see first record in table) .
Create a new record based on the above, rename ACCT to _X and delete the existing records it has used
End result of the above looks like this:
ACCT ID QTY LEI
A_X 2 200 NULL
A_X 3 500 0
BB_X 2 300 NULL
BB_X 3 300 0
Not sure what the best way of approaching this is, any ideas on this?
use string operations (like SubString and IndexOf) to parse the name of the account
use group by and aggregate functions (i.e. Sum) to calculate the results
insert the results into a temp table, delete the original data, insert back into the original table

SQL conditional extraction

I need a SQL query which allow me to extract the current value of a column if this column has not be modified since the add of the object.
Or the last before the current value if the column was modified.
Note that the current value is saved in a table A and the history of modification in table B
Table A
ID
STATUS
other columns ....
Table B
ID
items_ID (which is the ID of element in table A)
modif_ID (indicate which column was modified)
old_value
new_value
other columns..
Thanks in advance,
Imene.
For exemple, For table A
id STATUS Title Description User
1 Closed Help Need help for configuring Apache IBH
2 Solved DSL DSL is down IBH
3 Assign Hardware Need new network cards IBH
For table B
id Items_id Modif_id Date_mod Old_value New value
1 1 1 12-02-2014 Assign solved
2 1 1 15-02-2014 solved closed
3 3 1 20-02-2014 New Assign
3 3 4 21-02-2014 hard Hardware
All modif where the modif_id!=1 are ignored.
For each element id (Table A), we extract the current status if the status dosen’t change or the last before the current value if the status is changed one or more time. The expected result is:
id STATUS
1 solved
2 solved
3 New