Sometimes a quick sum of the used bytes in DBA_SEGMENTS is not enough to find the total size of a table.
If you have Large Object type columns defined in the table, the total table size can potentially be far greater than what you'd think.
Let's look at an example.
I have two tables in two differen schemas, with the same name. The tables are identical, and they both contain a LOB column:
SQL> desc livedocs.documents
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 ID                                        NOT NULL NUMBER(19)
 VERSION                                            NUMBER(19)
 DOC_ID                                             NOT NULL NUMBER(19)
 TYPE                                               NOT NULL VARCHAR2(255 CHAR)
 NUM_PAGES                                          NUMBER(15)
 CREATED                                            TIMESTAMP(6)
 LAST_CHANGED                                       TIMESTAMP(6)
 CONTENTS                                           NOT NULL BLOB
Check the tables' sizes:
SELECT OWNER,SEGMENT_NAME,SUM(BYTES)/1024/1024/1024 "table size (GB)" 
FROM DBA_SEGMENTS 
WHERE SEGMENT_NAME IN ('DOCUMENTS') 
AND OWNER IN ('LIVEDOCS','ARCHIVEDDOCS')
GROUP BY OWNER,SEGMENT_NAME;
Result:
   | OWNER |    SEGMENT_NAME |    table size (GB) |    
    | LIVEDOCS |      DOCUMENTS |      2,5  |    
    | ARCHIVEDDOCS |      DOCUMENTS |      1,875  |    
Let's find the name of the LOB segments and their corresponding indexes:
(The LOB indexes are internal data structures only. See 
this post.)
SELECT OWNER,TABLE_NAME,SEGMENT_NAME,COLUMN_NAME,INDEX_NAME 
FROM DBA_LOBS 
WHERE TABLE_NAME='DOCUMENTS' 
AND OWNER IN ('LIVEDOCS','ARCHIVEDDOCS');
   | OWNER |    TABLE_NAME |    SEGMENT_NAME |    COLUMN_NAME |    INDEX_NAME |    
    | ARCHIVEDDOCS |      DOCUMENTS |      ARCHIVED_DOCS_LOB |      CONTENT |      SYS_IL0000123181C00008$$ |    
    | LIVEDOCS |      DOCUMENTS |      LIVE_DOCS_LOB |      CONTENT |      SYS_IL0000194213C00009$$ |    
How much space have been allocated to these LOB segments?
SELECT OWNER,SEGMENT_NAME,ROUND(SUM(BYTES)/1024/1024/1024) "LOB size (GB)" 
FROM DBA_SEGMENTS
WHERE SEGMENT_NAME IN 
    (
    SELECT SEGMENT_NAME 
    FROM DBA_LOBS WHERE TABLE_NAME='DOCUMENTS'
    AND OWNER IN ('LIVEDOCS','ARCHIVEDDOCS')
    )
GROUP BY OWNER,SEGMENT_NAME 
; 
   | OWNER |    SEGMENT_NAME |    LOB size (GB) |    
    | LIVEDOCS |      LIVE_DOCS_LOB |      1256  |    
    | ARCHIVEDDOCS |      ARCHIVED_DOCS_LOB |      3642  |    
Putting it together, you can list both the table and its dependent LOB segments like this:
SELECT S.OWNER "Owner",NVL(S.SEGMENT_NAME, 'TABLE TOTAL SIZE') "Segment name",ROUND(SUM(S.BYTES)/1024/1024/1024,1) "Segment size (GB)"
FROM  DBA_SEGMENTS S 
WHERE S.SEGMENT_NAME IN ('DOCUMENTS')
AND   S.OWNER IN ('LIVEDOCS','ARCHIVEDOCS')
OR    S.SEGMENT_NAME IN (
                    (
                        SELECT L.SEGMENT_NAME FROM DBA_LOBS L 
                        WHERE L.TABLE_NAME = 'DOCUMENTS' 
                        AND L.OWNER = S.OWNER 
                        AND L.OWNER in ('LIVEDOCS','ARCHIVEDOCS')
                    )
)
GROUP BY S.OWNER,ROLLUP(S.SEGMENT_NAME)
ORDER BY 1,2,3; 
The resulting listing is:
   | Owner |    Segment name |    Segment size (GB) |    
    | ARCHIVEDDOCS |      ARCHIVED_DOCS_LOB |      3642,4  |    
    | ARCHIVEDDOCS |      DOCUMENTS |      1,9  |    
    | ARCHIVEDDOCS |      TABLE TOTAL SIZE |      3644,3  |    
    | LIVEDOCS |      DOCUMENTS |      2,5  |    
    | LIVEDOCS |      LIVE_DOCS_LOB |      1255,9  |    
    | LIVEDOCS |      TABLE TOTAL SIZE |      1258,4  |    
Addendum, 2025-02-06:
With assistance from Chat GPT, I realized that a better query would be to use named subqueries, or CTEs (Common Table Expressions). They can be built using the WITH-clause in SQL, and referred to in the main query:
set lines 200
col OWNER format a30
col TABLE_NAME format a30
col TABLE_SIZE_GB format 99
col LOB_SEGMENT_NAME format a30
col LOB_COLUMN_NAME format a30
col LOB_DATA_TYPE format a30
col LOB_SIZE_GB format 999 
BREAK ON OWNER
WITH
    -- CTE to get the tables with LOB objects
    lob_tables AS (
        SELECT DISTINCT TABLE_NAME, OWNER
        FROM DBA_TAB_COLUMNS
        WHERE OWNER = 'SCOTT'
          AND DATA_TYPE IN ('NCLOB', 'BLOB', 'RAW'  )
          AND TABLE_NAME NOT LIKE 'BIN$%'
    ),
    -- CTE to get LOB segment names with their corresponding table and column names
    lob_segments AS (
        SELECT DISTINCT L.OWNER,
                        L.TABLE_NAME,
                        L.SEGMENT_NAME AS LOB_SEGMENT_NAME,
                        C.COLUMN_NAME AS LOB_COLUMN_NAME,
                        C.DATA_TYPE AS LOB_DATA_TYPE
        FROM DBA_LOBS L
        JOIN DBA_TAB_COLUMNS C
          ON L.TABLE_NAME = C.TABLE_NAME
         AND L.COLUMN_NAME = C.COLUMN_NAME
        WHERE L.OWNER = 'SCOTT'
    ),
    -- CTE to get the table size in GB
    table_sizes AS (
        SELECT S.OWNER,
               S.SEGMENT_NAME AS TABLE_NAME,
               ROUND(SUM(S.BYTES)/1024/1024/1024, 1) AS TABLE_SIZE_GB
        FROM DBA_SEGMENTS S
        WHERE S.OWNER = 'SCOTT'
          AND EXISTS (SELECT 1 FROM lob_tables LT WHERE LT.TABLE_NAME = S.SEGMENT_NAME)
        GROUP BY S.OWNER, S.SEGMENT_NAME
    ),
    -- CTE to get the LOB size in GB
    lob_sizes AS (
        SELECT L.OWNER,
               L.TABLE_NAME,
               L.SEGMENT_NAME AS LOB_SEGMENT_NAME,
               ROUND(SUM(S.BYTES)/1024/1024/1024, 1) AS LOB_SIZE_GB
        FROM DBA_LOBS L
        JOIN DBA_SEGMENTS S
          ON L.SEGMENT_NAME = S.SEGMENT_NAME
         AND L.OWNER = S.OWNER
        WHERE L.OWNER = 'SCOTT'
        GROUP BY L.OWNER, L.TABLE_NAME, L.SEGMENT_NAME
    )
-- Final query to combine everything
SELECT TS.OWNER,
       TS.TABLE_NAME,
       TS.TABLE_SIZE_GB,
       LS.LOB_SEGMENT_NAME,
       LS.LOB_COLUMN_NAME,
       LS.LOB_DATA_TYPE,
       LZ.LOB_SIZE_GB
FROM table_sizes TS
JOIN lob_segments LS
  ON TS.OWNER = LS.OWNER
 AND TS.TABLE_NAME = LS.TABLE_NAME
JOIN lob_sizes LZ
  ON LS.OWNER = LZ.OWNER
 AND LS.LOB_SEGMENT_NAME = LZ.LOB_SEGMENT_NAME
ORDER BY TS.OWNER, TS.TABLE_NAME, LS.LOB_SEGMENT_NAME;
This gives you a practical row-by-row view of everything you need to know about the LOB segments:
| OWNER | 
TABLE_NAME | 
TABLE_SIZE_GB | 
LOB_SEGMENT_NAME | 
LOB_COLUMN_NAME | 
LOB_DATA_TYPE | 
LOB_SIZE_GB | 
| SCOTT | 
TABLE1 | 
0  | 
SYS_LOB0003064134C00015$$ | 
MYCOL1 | 
NCLOB | 
0  | 
|   | 
TABLE1 | 
0  | 
SYS_LOB0003064134C00028$$ | 
MYCOL2 | 
NCLOB | 
0  | 
|   | 
TABLE2 | 
0,2  | 
SYS_LOB0003064148C00005$$ | 
MYCOL1 | 
NCLOB | 
1  | 
|   | 
TABLE2 | 
0,2  | 
SYS_LOB0003064148C00017$$ | 
MYCOL2BLOB | 
BLOB | 
0  | 
|   | 
TABLE3 | 
0,2  | 
SYS_LOB0003064159C00004$$ | 
MYCOL1 | 
NCLOB | 
237  | 
|   | 
TABLE3 | 
0,1  | 
SYS_LOB0003064143C00003$$ | 
MYCOL1 | 
NCLOB | 
0  |