Skip to content
Report · Financials

Income statement by month

Income and expense accounts by posting period for two years, laid out for the Statement widget with sections and net income.

  • statement
  • profit and loss
  • monthly
  • drill-through
Sample preview, fictional dataYour own figures appear after import.

01

About this report

One row per income, cost of sales, expense, other income and other expense account per posting period, for the last 24 months. Amounts are in base currency from the primary accounting book. Income reads positive and costs negative, so the statement ends on net income.

The columns are set up for the Statement widget. Use Account for rows, Section for sections in Section order, Month for columns and the sum of Amount as the value. That gives sections with subtotals, a Total column and net income as the last line. The Financial overview dashboard in this library has one ready. In the table, click an Amount to open General ledger postings for that account and month. In a OneWorld account, amounts of subsidiaries with different base currencies are added without translation.

02

Sample preview

Fictional figures in the shape you will see. Yours come from your account.

MonthSectionAccount numberAccountAmount
2026-08Income40004000 Product sales412,300
2026-08Income41004100 Services188,450
2026-08Cost of Sales50005000 Cost of goods sold-201,900
2026-08Expense60006000 Salaries and wages-142,800
2026-08Expense63106310 Hosting and software-18,450.40
2026-08Other Expense81008100 Exchange gain or loss-1,220.80

03

The SuiteQL

This is the query each report runs. Read it, copy it, or change it after import.

Income statement by month
SELECT TO_CHAR(p.startdate, 'YYYY-MM') AS period,
       CASE a.accttype WHEN 'Income' THEN 'Income' WHEN 'COGS' THEN 'Cost of Sales' WHEN 'Expense' THEN 'Expense'
                       WHEN 'OthIncome' THEN 'Other Income' ELSE 'Other Expense' END AS section,
       CASE a.accttype WHEN 'Income' THEN 1 WHEN 'COGS' THEN 2 WHEN 'Expense' THEN 3 WHEN 'OthIncome' THEN 4 ELSE 5 END AS section_order,
       a.acctnumber AS account_number,
       a.displaynamewithhierarchy AS account,
       SUM(-tal.amount) AS amount
  FROM transactionaccountingline tal
  JOIN accountingbook ab ON ab.id = tal.accountingbook AND ab.isprimary = 'T'
  JOIN transaction t ON t.id = tal.transaction
  JOIN account a ON a.id = tal.account
  JOIN accountingperiod p ON p.id = t.postingperiod
 WHERE tal.posting = 'T'
   AND a.accttype IN ('Income', 'COGS', 'Expense', 'OthIncome', 'OthExpense')
   AND p.startdate >= ADD_MONTHS(TRUNC(SYSDATE, 'MM'), -23)
   AND p.startdate <= SYSDATE
 GROUP BY TO_CHAR(p.startdate, 'YYYY-MM'), a.accttype, a.acctnumber, a.displaynamewithhierarchy
 ORDER BY period, section_order, account_number, account
General ledger postings
SELECT TO_CHAR(p.startdate, 'YYYY-MM') AS period,
       TO_CHAR(t.trandate, 'YYYY-MM-DD') AS tran_date,
       BUILTIN.DF(t.type) AS type,
       NVL(t.tranid, t.transactionnumber) AS document,
       a.displaynamewithhierarchy AS account,
       BUILTIN.DF(a.accttype) AS account_type,
       NVL(e.altname, e.entityid) AS name,
       tl.memo AS memo,
       tal.debit AS debit,
       tal.credit AS credit,
       -tal.amount AS amount
  FROM transactionaccountingline tal
  JOIN accountingbook ab ON ab.id = tal.accountingbook AND ab.isprimary = 'T'
  JOIN transaction t ON t.id = tal.transaction
  JOIN account a ON a.id = tal.account
  JOIN accountingperiod p ON p.id = t.postingperiod
  JOIN transactionline tl ON tl.transaction = tal.transaction AND tl.id = tal.transactionline
  LEFT JOIN entity e ON e.id = t.entity
 WHERE tal.posting = 'T'
   AND tal.amount <> 0
   AND p.startdate >= ADD_MONTHS(TRUNC(SYSDATE, 'MM'), -23)
 ORDER BY t.trandate DESC, document

04

Appears in

ReportFinancials

Income statement by month

Screenshot of the Income statement by month report in HiScale Advanced Reports, filled with fictional sample data
Sample preview, fictional dataOpen image full size (opens in a new tab)