/

/

SAP, Oracle, NetSuite: How to Query Any ERP Database with AI

Content

SAP, Oracle, NetSuite: How to Query Any ERP Database with AI

SAP, Oracle, NetSuite: How to Query Any ERP Database with AI

SAP, Oracle, NetSuite: How to Query Any ERP Database with AI

Your company runs on an ERP. SAP, Oracle, NetSuite, Microsoft Dynamics, or Odoo. It manages everything from finances to inventory to HR. But when you need a specific piece of data that's not in a standard report, you're stuck.

Each ERP has its own database, its own table naming conventions, and its own query quirks. Learning SQL is hard enough. Learning SQL for your specific ERP is harder.

Unless you let AI do the translation.

ERP Database Cheat Sheet

ERP System

Database

Table Prefix

Access Method

SAP S/4HANA

SAP HANA

No standard prefix

HANA Studio, DBeaver

SAP ECC

Various (Oracle, SQL Server, DB2)

No prefix

SE16, SQVI

Oracle ERP Cloud

Oracle DB

Schema-based

OTBI, SQL Developer

NetSuite

Oracle

No prefix

SuiteAnalytics, ODBC

Dynamics 365

SQL Server / Dataverse

dbo.

SSMS, Power Query

Odoo

PostgreSQL

No prefix

pgAdmin, DBeaver

SAP Queries

SAP's table names are cryptic but consistent. Once you know the key tables, queries become straightforward.

Key SAP Tables

Table

Description

BKPF

Accounting document headers

BSEG

Accounting document line items

KNA1

Customer master data

LFA1

Vendor master data

MARA

Material master

VBAK

Sales order headers

VBAP

Sales order line items

EKKO

Purchase order headers

EKPO

Purchase order line items

SAP: Open Sales Orders

SELECT 
    v.VBELN as order_number,
    v.ERDAT as created_date,
    v.KUNNR as customer,
    k.NAME1 as customer_name,
    p.MATNR as material,
    p.KWMENG as quantity,
    p.NETWR as net_value,
    p.WAERK as currency
FROM VBAK v
JOIN VBAP p ON v.VBELN = p.VBELN
JOIN KNA1 k ON v.KUNNR = k.KUNNR
WHERE v.GBSTK != 'C'
ORDER BY v.ERDAT DESC;

Oracle ERP Cloud Queries

Oracle ERP Cloud uses Fusion-style table names that are more readable than SAP's.

Oracle: AP Invoice Summary

SELECT 
    pv.vendor_name,
    ai.invoice_num,
    ai.invoice_date,
    ai.invoice_amount,
    ai.amount_paid,
    ai.invoice_amount - ai.amount_paid as balance,
    ai.payment_status_flag
FROM ap_invoices_all ai
JOIN poz_suppliers pv ON ai.vendor_id = pv.vendor_id
WHERE ai.invoice_date >= ADD_MONTHS(SYSDATE, -6)
ORDER BY ai.invoice_amount DESC;

Oracle: GL Balance by Account

SELECT 
    gcc.segment1 as company,
    gcc.segment2 as account,
    gb.period_name,
    gb.begin_balance_dr - gb.begin_balance_cr as opening_balance,
    gb.period_net_dr - gb.period_net_cr as net_activity,
    (gb.begin_balance_dr + gb.period_net_dr) - 
    (gb.begin_balance_cr + gb.period_net_cr) as closing_balance
FROM gl_balances gb
JOIN gl_code_combinations gcc ON gb.code_combination_id = gcc.code_combination_id
WHERE gb.actual_flag = 'A'
  AND gb.period_name = 'MAR-24'
ORDER BY gcc.segment2;

NetSuite Queries

NetSuite provides SuiteAnalytics Connect for direct SQL access via ODBC.

NetSuite: Customer Sales Summary

SELECT 
    c.companyName as customer,
    COUNT(DISTINCT t.id) as transaction_count,
    SUM(tl.netAmount) as total_revenue,
    MAX(t.tranDate) as last_purchase
FROM customer c
JOIN transaction t ON c.id = t.entity
JOIN transactionLine tl ON t.id = tl.transaction
WHERE t.type = 'SalesOrd'
  AND t.tranDate >= ADD_MONTHS(SYSDATE, -12)
GROUP BY c.companyName
ORDER BY total_revenue DESC
FETCH FIRST 20 ROWS ONLY;

Microsoft Dynamics 365 Queries

Dynamics: Open Purchase Orders

SELECT 
    ph.PurchId as po_number,
    ph.OrderAccount as vendor_id,
    v.Name as vendor_name,
    pl.ItemId as item,
    pl.PurchQty as quantity,
    pl.PurchPrice as unit_price,
    pl.LineAmount as line_total,
    ph.PurchStatus as status
FROM PurchTable ph
JOIN PurchLine pl ON ph.PurchId = pl.PurchId
JOIN VendTable v ON ph.OrderAccount = v.AccountNum
WHERE ph.PurchStatus IN (1, 2)
ORDER BY ph.CreatedDateTime DESC;

Odoo Queries (PostgreSQL)

Odoo: Invoice Aging Report

SELECT 
    rp.name as customer,
    am.name as invoice_number,
    am.invoice_date,
    am.invoice_date_due as due_date,
    am.amount_total,
    am.amount_residual as balance_due,
    CURRENT_DATE - am.invoice_date_due as days_overdue
FROM account_move am
JOIN res_partner rp ON am.partner_id = rp.id
WHERE am.move_type = 'out_invoice'
  AND am.payment_state != 'paid'
  AND am.state = 'posted'
ORDER BY days_overdue DESC;

The AI Advantage: One Tool for Every ERP

Each ERP has different table names, different SQL dialects, different conventions. Learning them all is impractical. AI2SQL handles the differences for you.

Just tell it:

  • Your ERP system (SAP, Oracle, NetSuite, etc.)

  • What data you need in plain English

  • Any filters or groupings you want

AI2SQL generates the correct SQL for your specific database. It knows that SAP uses VBAK for sales orders while Oracle uses oe_order_headers_all. It knows NetSuite uses SuiteQL syntax while Odoo runs on PostgreSQL.

Examples

  • "Show me overdue AP invoices in SAP" → query with BKPF/BSEG tables

  • "Top 10 customers by revenue in NetSuite" → query with transaction/transactionLine

  • "Open purchase orders in Dynamics 365" → query with PurchTable/PurchLine

  • "Invoice aging report in Odoo" → query with account_move/res_partner

Get Started

Your ERP database holds the answers to every business question. You just need to know how to ask. AI2SQL translates your questions into the right SQL for your system.

Try it free at ai2sql.io. No SQL knowledge required. No ERP expertise needed.

Share this

More Articles

More Articles

More Articles