BKPF BSEG Join: Keys, S/4HANA Changes and ACDOCA
Join SAP BKPF to BSEG on MANDT, BUKRS, BELNR and GJAHR, sign amounts with SHKZG, why BSEG was a cluster table, and when to read ACDOCA in S/4HANA instead.
On this page
To join BKPF to BSEG, match all four header keys, MANDT, BUKRS, BELNR and GJAHR; BSEG adds BUZEI as the line number, so one header fans out to its line items and nothing else. BKPF is the accounting document header, BSEG the accounting document segment (the lines), and that shape is the same in SAP ECC and S/4HANA. What changed is everything around it: in ECC, BSEG was a cluster table that ABAP could not join or aggregate, and in S/4HANA the reporting job moved to ACDOCA, the universal journal, while BSEG stayed on as the entry view. This page is the reference for all three: the join, why it used to be awkward, and when to stop using it.
The tables and their keys
| Table | What it holds | Key | One row per |
|---|---|---|---|
BKPF | Accounting document header | MANDT, BUKRS, BELNR, GJAHR | Document |
BSEG | Accounting document segment: the entry-view line items | MANDT, BUKRS, BELNR, GJAHR, BUZEI | Document line |
ACDOCA | Universal journal (S/4HANA): the ledger-view line items | RCLNT, RLDNR, RBUKRS, GJAHR, BELNR, DOCLN | Document line per ledger |
A document is unique only across all four header fields. Leaving out BUKRS or GJAHR is the classic mistake: BELNR repeats across company codes and fiscal years, so a two-field join silently multiplies rows.
The fields you reach for most:
| Table | Field | Meaning |
|---|---|---|
| BKPF | BLART | Document type |
| BKPF | BUDAT, BLDAT | Posting date, document date |
| BKPF | XBLNR | Reference (often the external document number) |
| BKPF | USNAM | User who entered the document |
| BSEG | BUZEI | Line item number, three digits, so at most 999 lines per document |
| BSEG | KOART | Account type: S G/L, D customer, K vendor, A asset, M material |
| BSEG | HKONT | G/L account |
| BSEG | SHKZG | Debit/credit indicator: S debit, H credit |
| BSEG | DMBTR, WRBTR | Amount in local currency, amount in document currency, both unsigned |
| BSEG | AUGBL, AUGDT | Clearing document and clearing date |
The join
SELECT
h.bukrs,
h.belnr,
h.gjahr,
h.blart, -- document type
h.budat, -- posting date
l.buzei, -- line item number
l.koart, -- account type
l.hkont, -- G/L account
l.shkzg, -- debit/credit indicator (S/H)
l.dmbtr -- amount in local currency, unsigned
FROM bkpf AS h
JOIN bseg AS l
ON l.mandt = h.mandt
AND l.bukrs = h.bukrs
AND l.belnr = h.belnr
AND l.gjahr = h.gjahr
WHERE h.mandt = '100'
AND h.bukrs = '1000'
AND h.gjahr = '2026'
ORDER BY h.belnr, l.buzei;
This is plain SQL of the kind you would run against a replicated copy or an S/4HANA system. Treat client, company code and year as placeholders.
Amounts are unsigned: read SHKZG
DMBTR and WRBTR are always positive. The direction lives in SHKZG (S = debit, H = credit), so summing DMBTR directly gives gross turnover, not a net balance.
SELECT
l.hkont,
SUM(CASE WHEN l.shkzg = 'H' THEN -l.dmbtr ELSE l.dmbtr END) AS net_local
FROM bkpf AS h
JOIN bseg AS l
ON l.mandt = h.mandt
AND l.bukrs = h.bukrs
AND l.belnr = h.belnr
AND l.gjahr = h.gjahr
WHERE h.mandt = '100'
AND h.bukrs = '1000'
AND h.gjahr = '2026'
GROUP BY l.hkont;
Why BSEG was awkward in ECC: a cluster table
In classic SAP ERP, BSEG is not an ordinary database table. It is a cluster table, physically stored inside the table cluster RFBLG, which is keyed on the document header fields. The ABAP Keyword Documentation lists what that costs in Open SQL: no joins with pooled or cluster tables, no GROUP BY or HAVING, and no column comparisons on the right side of a WHERE condition. Both SQL blocks above are therefore impossible as Open SQL on a classic ECC database.
SAP's answer was redundancy. The secondary index tables duplicate a subset of BSEG in transparent tables you can join and index: BSIS/BSAS for G/L items, BSID/BSAD for customers, BSIK/BSAK for vendors, with I for open and A for cleared items. Line-item reports such as FBL3N, FBL5N and FBL1N read those, not BSEG.
The idiomatic ECC pattern in ABAP is header first, lines second, with the full key:
SELECT bukrs, belnr, gjahr, blart, budat
FROM bkpf
WHERE bukrs = @lv_bukrs
AND gjahr = @lv_gjahr
AND blart = 'SA'
INTO TABLE @DATA(lt_head).
IF lt_head IS NOT INITIAL.
SELECT bukrs, belnr, gjahr, buzei, hkont, shkzg, dmbtr
FROM bseg
FOR ALL ENTRIES IN @lt_head
WHERE bukrs = @lt_head-bukrs
AND belnr = @lt_head-belnr
AND gjahr = @lt_head-gjahr
INTO TABLE @DATA(lt_items).
ENDIF.
(The inline-declaration syntax needs a recent ABAP release; on an older ECC the same logic uses classic SELECT ... INTO TABLE with declared internal tables.)
ECC on SAP HANA is the halfway house. Migrating an ERP system to the HANA database declusters its cluster tables into transparent ones as standard, which is why SAP has a knowledge-base article for the cases where some weren't, and a FAQ specifically on converting cluster tables such as BSEG. One practical trap follows: a cluster table returned rows in key order as a side effect, and a declustered one does not. Code that relied on that order needs an explicit ORDER BY or a SORT.
What changed in S/4HANA
Two things happened at once. BSEG became a normal transparent table, and ACDOCA took over the ledger.
| Question | ECC | S/4HANA |
|---|---|---|
| Is BSEG a cluster table? | Yes, in RFBLG (unless the database is HANA) | No, a transparent table |
| What does BSEG hold? | All FI line items | The entry view: one row per document line, not per ledger, plus open-item details such as payment terms |
| Where do balances come from? | Totals tables (GLT0, FAGLFLEXT) and index tables | ACDOCA; the old totals and index tables are compatibility views that read it |
| Are amounts signed? | No, use SHKZG | In BSEG, still no; in ACDOCA, yes (HSL in company code currency, KSL in group currency, and further currency fields), with DRCRK as the indicator |
| Line limit per document | 999 (BUZEI) | 999 in BSEG still; ACDOCA-DOCLN has six digits, and BSEG lines can be summarized |
| Multiple ledgers | Separate new-G/L tables | One ACDOCA row per line per ledger, distinguished by RLDNR |
SAP's own documentation calls ACDOCA the single source of truth for accounting, and the compatibility views exist so that old code selecting from BSIS or FAGLFLEXT keeps running. Running is not the same as being the right source: a compatibility view is ACDOCA wearing an old name.
Three consequences matter for anyone reconciling the two. Line numbers don't map one-to-one: DOCLN is not BUZEI, ACDOCA can carry lines that BSEG summarized away, and every extra ledger adds rows. Some things never reach ACDOCA: SAP's knowledge base notes that noted items such as down-payment requests live in BSEG only. And on S/4HANA Cloud public edition you don't read tables at all: the released CDS views are the interface, with I_JournalEntry for the header, I_JournalEntryItem for universal-journal items and I_OperationalAcctgDocItem for the entry-view items that correspond to BSEG.
BSEG didn't disappear in S/4HANA; it stopped being the answer to "what's the balance?". Ask ACDOCA that question, and keep BSEG for "what exactly was posted on this document?"
When to read ACDOCA instead
Use ACDOCA (or I_JournalEntryItem) for balances, trial balances, P&L and balance-sheet slices, anything by profit centre, segment or cost object, and any question that is really "per ledger". Always restrict the ledger: without RLDNR, a company with a leading and a local ledger double-counts.
SELECT
racct, -- G/L account
SUM(hsl) AS net_local -- already signed, company code currency
FROM acdoca
WHERE rclnt = '100'
AND rldnr = '0L' -- the ledger you report on
AND rbukrs = '1000'
AND gjahr = '2026'
GROUP BY racct;
Keep the BKPF/BSEG join for document-level work: an audit trail or a drill-down from a document number, open-item and payment-term detail, clearing analysis, noted items, and tracing what a specific process posted. Tracing what an electronic bank statement run or a treasury TBB1 flow posting actually created is the everyday example.
Performance guidance
- Always restrict company code and fiscal year, and the client if you are outside ABAP. On ACDOCA add the ledger. Most runaway queries on either table are missing one of these.
- Select the columns you need. BSEG and ACDOCA are wide;
SELECT *on ACDOCA pulls hundreds of columns from a column store. - ECC on a classic database: never search BSEG by a non-key field. Go through the index tables or through BKPF, then read BSEG by full key.
- S/4HANA: aggregate in the database. A
GROUP BYon ACDOCA is what the column store is built for; pulling line items into ABAP to sum them is the ECC habit to drop. - Don't join
ACDOCA-DOCLNtoBSEG-BUZEIand expect a one-to-one result. Reconcile at document level (company code, document number, year), then compare totals. - Sort explicitly. No former cluster table guarantees order any more.
Traps worth checking in any report
- A join on
BELNRalone, or onBELNRandBUKRSwithoutGJAHR: correct in testing, wrong in the first year-end. - Summing unsigned
DMBTR: a balance that is really turnover. - Summing ACDOCA without a ledger filter: every value doubled for each parallel ledger.
- Reconciling ACDOCA line counts to BSEG line counts: summarization and ledgers make them differ by design.
For the treasury view of these tables, where TBB1 postings and the Treasury subledger meet the general ledger, see the SAP treasury tables reference; for what changes in a conversion, see migrating SAP treasury from ECC to S/4HANA.
See also SAP treasury tables, SAP TRM accounting and posting architecture and the SAP Treasury hub.
Primary sources
SAP ERP 6.0 (ECC) on any database, including ECC on SAP HANA, and SAP S/4HANA on-premise and private edition. Table and field names are SAP data-dictionary names; the SQL and ABAP blocks are illustrative sketches for reading a replica or an S/4HANA system, not production code, and S/4HANA Cloud public edition exposes the released CDS views rather than the tables. Claims checked on 2026-09-25 through cross-checked excerpts of the listed sources.
- SAP Help โ Detection Method: OTA Uses Bank Account of Regular Vendor (BKPF as accounting document header, BSEG as accounting document segment at database level) โ accessed 2026-08-02
- SAP Help โ JVA on ACDOCA (the universal journal as the single source of truth for accounting) โ accessed 2026-08-02
- ABAP Keyword Documentation (7.51) โ Restrictions in Pooled Tables and Cluster Tables (no joins, no GROUP BY/HAVING) โ accessed 2026-09-25
- SAP KBA 1960840 โ Not all tables have been declustered/depooled on migration to SoH โ accessed 2026-09-25
- SAP KBA 2769310 โ Frequently-asked questions about table conversion on cluster tables such as BSEG โ accessed 2026-09-25
- SAP Community (SAP) โ 999: The Number of the BSEG (BUZEI limit, BSEG summarization in S/4HANA) โ accessed 2026-09-25
- SAP KBA 3128916 โ FI document has 999 limit of line item in S/4HANA? โ accessed 2026-09-25
- SAP KBA 3523400 โ Overview of the compatibility view topic in the context of SAP HANA (SAP S/4HANA) โ accessed 2026-09-25
- SAP KBA 3513673 โ CDS view for noted items related to down payment request (noted items in BSEG, not ACDOCA) โ accessed 2026-09-25
- SAP Help โ CDS Views for General Ledger Accounting (SAP S/4HANA) โ accessed 2026-09-25
- SAP Help โ Accounting Document Item: Operational View โ accessed 2026-09-25
Frequently asked questions
(4)
Which fields join BKPF to BSEG in SAP FI?
All four together: MANDT (client), BUKRS (company code), BELNR (document number) and GJAHR (fiscal year). BELNR is only unique within a company code and fiscal year, so a join on document number alone fans out across every company code and year that reuses it. BSEG's own key adds BUZEI, the line item number, which is why one BKPF row joins to many BSEG rows.
Why can't I just sum DMBTR to get an account balance?
DMBTR is stored as a positive number; the debit or credit direction is in SHKZG, where S is debit and H is credit. Summing DMBTR gives gross turnover, not a balance. Flip the sign for H rows, for example SUM(CASE WHEN shkzg = 'H' THEN -dmbtr ELSE dmbtr END). ACDOCA avoids the problem because its amount fields such as HSL are already signed.
Is BSEG still used in S/4HANA?
Yes. BSEG still exists in S/4HANA as a transparent table rather than a cluster table, and it still holds the entry view of each accounting document, one row per document line, along with open-item details such as payment terms. The ledger view lives in ACDOCA, the universal journal, which holds one row per line per ledger and is the source for balances and reporting. The old index and totals tables such as BSIS and FAGLFLEXT survive only as compatibility views.
Should I join BKPF and BSEG or read ACDOCA on S/4HANA?
Read ACDOCA, or its released CDS views, for balances, ledger-specific values and anything that needs controlling or profitability fields, filtering on the ledger. Keep the BKPF/BSEG join for document-level work: audit trails, drill-downs from a document number, open-item and payment-term detail, and noted items such as down-payment requests, which sit in BSEG but not in ACDOCA.