Skip to main content

Junction Tables Reference

A comprehensive reference of NetSuite's junction tables - hidden tables that link records together in one-to-many and many-to-many relationships.


What Are Junction Tables?

JUNCTION TABLE CONCEPT
═══════════════════════════════════════════════════════════════════════════════

ONE-TO-MANY (Sublist pattern) MANY-TO-MANY (Mapping pattern)
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Transaction │ │ Transaction │ │ Customer │ │ Lead Source │
│ Header │ │ Line │ │ │ │ List │
│ ID: 100 │────▶│ Trans: 100 │ │ ID: 50 │ │ ID: 1-5 │
│ │ │ Line: 1,2,3 │ │ │ │ │
└─────────────┘ └─────────────┘ └──────┬──────┘ └──────┬──────┘
│ │
Parent table Junction table │ ┌───────────┐ │
(1 row) (many rows) └──▶│ map_table │◀──┘
│ 50 → 1 │
│ 50 → 3 │
│ 50 → 5 │
└───────────┘

Transaction Junction Tables

Transaction to Lines

TableLinksPurposeKey Columns
TransactionLineTransaction → LinesItem lines, expense linestransaction, linesequencenumber, item, quantity, amount
TransactionAccountingLineTransaction → GL LinesDebit/Credit entriestransaction, transactionline, account, debit, credit
InventoryAssignmentTransactionLine → Lot/SerialInventory detailtransaction, transactionline, inventorynumber, quantity, binnumber
TransactionShipGroupTransaction → Shipping GroupsMultiple ship-to addressestransaction, shipaddress, shipmethod
TableLinksPurposeKey Columns
NextTransactionLineLinkParent → Child (line)SO → Invoice, PO → Receiptpreviousdoc, nextdoc, previousline, nextline, quantity
PreviousTransactionLineLinkChild → Parent (line)Reverse lookupSame as above
NextTransactionLinkParent → Child (header)Header-only linkingpreviousdoc, nextdoc
PreviousTransactionLinkChild → Parent (header)Reverse lookupSame as above

Example: Transaction with Lines and GL

-- Complete transaction with lines and accounting impact
SELECT
t.tranid,
t.trandate,
tl.linesequencenumber AS line,
BUILTIN.DF(tl.item) AS item,
tl.quantity,
tl.amount AS line_amount,
BUILTIN.DF(tal.account) AS gl_account,
tal.debit,
tal.credit
FROM Transaction t
INNER JOIN TransactionLine tl ON tl.transaction = t.id
LEFT JOIN TransactionAccountingLine tal
ON tal.transaction = t.id
AND tal.transactionline = tl.id
WHERE t.id = 12345
ORDER BY tl.linesequencenumber, tal.account

Item Junction Tables

Item Components and Relationships

TableLinksPurposeKey Columns
ItemMemberAssembly/Kit → ComponentsBOM componentsparentitem, item, quantity, memberunit
ItemVendorItem → VendorsPreferred vendorsitem, vendor, purchaseprice, preferredvendor
ItemImageItem → ImagesProduct photositem, name, alttagcaption
ItemPriceItem → Price LevelsPricing matrixitem, currency, pricelevel, unitprice

Item Location Tables

TableLinksPurposeKey Columns
InventoryItemLocationsItem → LocationsStock by locationitem, location, quantityonhand, quantityavailable
AggregateItemLocationItem → Location (summary)Aggregated inventoryitem, location, quantityonhand, averagecost
ItemLocationConfigurationItem → Location SettingsReorder points, binsitem, location, preferredbin, reorderpoint

Lot/Serial Tables

TableLinksPurposeKey Columns
InventoryNumberItem → Serial/Lot NumbersSerial/lot masteritem, inventorynumber, expirationdate, status
InventoryNumberLocationInventoryNumber → LocationsLot/serial by locationinventorynumber, location, quantityonhand
InventoryBalanceItem → Location → BinCurrent bin inventoryitem, location, binnumber, quantityonhand

Example: Item with Components and Vendors

-- Assembly item with BOM and vendor info
SELECT
parent.itemid AS assembly,
parent.displayname AS assembly_name,
member.itemid AS component,
im.quantity AS component_qty,
BUILTIN.DF(im.memberunit) AS uom,
iv.vendor,
BUILTIN.DF(iv.vendor) AS vendor_name,
iv.purchaseprice
FROM Item parent
INNER JOIN ItemMember im ON im.parentitem = parent.id
INNER JOIN Item member ON member.id = im.item
LEFT JOIN ItemVendor iv ON iv.item = member.id AND iv.preferredvendor = 'T'
WHERE parent.id = 500 -- Assembly item ID
ORDER BY im.linenumber

Entity Junction Tables

Customer/Vendor Relationships

TableLinksPurposeKey Columns
EntityAddressEntity → AddressesAddress bookentity, addressee, address1, city, state, zip
ContactEntity → ContactsRelated contactscompany, firstname, lastname, email, phone
CustomerSubsidiaryRelationshipCustomer → SubsidiariesMulti-subsidiaryentity, subsidiary
EntityGroupMemberGroup → MembersGroup membershipentitygroup, entity

Employee Tables

TableLinksPurposeKey Columns
EmployeeRolesForSearchEmployee → RolesRole assignmentsemployee, role
RolePermissionsRole → PermissionsPermission grantsrole, permission, level

Example: Customer with Addresses and Contacts

-- Customer with all addresses and primary contact
SELECT
c.id,
c.companyname,
c.email AS company_email,
addr.label AS address_type,
addr.addressee,
addr.address1,
addr.city,
addr.state,
addr.zip,
con.firstname || ' ' || con.lastname AS contact_name,
con.email AS contact_email,
con.phone AS contact_phone
FROM Customer c
LEFT JOIN EntityAddress addr ON addr.entity = c.id
LEFT JOIN Contact con ON con.company = c.id AND con.isprimarycontact = 'T'
WHERE c.id = 100
ORDER BY addr.label

File/Attachment Tables

TableLinksPurposeKey Columns
FileStandaloneFile cabinet entriesid, name, folder, filetype, url
MediaItemFolderFolder hierarchyFolder structureid, name, parent, appfolder
MessageFileMessage → FilesEmail attachmentsmessage, file
ItemImageItem → FileProduct imagesitem, name → joins to File

Example: Message with Attachments

-- Email messages with file attachments
SELECT
m.id AS message_id,
m.subject,
m.messagedate,
f.name AS attachment_name,
f.filetype,
f.filesize,
f.url
FROM Message m
INNER JOIN MessageFile mf ON mf.message = m.id
INNER JOIN File f ON f.id = mf.file
WHERE m.transaction = 12345
ORDER BY m.messagedate, f.name

Audit/History Tables

TableLinksPurposeKey Columns
SystemNoteAny Record → ChangesChange audit trailrecordid, recordtype, field, oldvalue, newvalue, date, name
LoginAuditUser → LoginsLogin historyuser, date, ipaddress, status
DeletedRecordN/ADeleted record logrecordtype, customrecordtype, name, deleteddate, deletedby

Example: Audit Trail for Transaction

-- All changes to a transaction
SELECT
sn.date AS change_date,
BUILTIN.DF(sn.name) AS changed_by,
sn.field AS field_changed,
sn.oldvalue,
sn.newvalue,
sn.context -- UIF=UI, SCH=Scheduled, SLT=Suitelet, etc.
FROM SystemNote sn
WHERE sn.recordid = 12345
AND sn.recordtype = -30 -- Transaction record type
ORDER BY sn.date DESC

Example: Line-Level Audit

-- Changes to specific transaction lines
SELECT
sn.date,
BUILTIN.DF(sn.name) AS changed_by,
sn.lineid AS line_number,
sn.field,
sn.oldvalue,
sn.newvalue
FROM SystemNote sn
WHERE sn.recordid = 12345
AND sn.lineid IS NOT NULL
ORDER BY sn.date DESC, sn.lineid

Currency/Rate Tables

TableLinksPurposeKey Columns
CurrencyRateCurrency → RatesHistorical exchange ratesbasecurrency, transactioncurrency, exchangerate, effectivedate
ConsolidatedExchangeRateSubsidiary → Period → RatesConsolidation ratesfromsubsidiary, tosubsidiary, period, currentrate, averagerate, historicalrate

Example: Historical Exchange Rate

-- Get exchange rate for a specific date
SELECT
cr.effectivedate,
BUILTIN.DF(cr.basecurrency) AS base,
BUILTIN.DF(cr.transactioncurrency) AS target,
cr.exchangerate
FROM CurrencyRate cr
WHERE cr.basecurrency = 1 -- USD
AND cr.transactioncurrency = 3 -- EUR
AND cr.effectivedate <= TO_DATE('2024-12-01', 'YYYY-MM-DD')
ORDER BY cr.effectivedate DESC
FETCH FIRST 1 ROW ONLY

Multi-Select Mapping Tables

Auto-generated for every multi-select field:

PatternStructureExample
map_{record}_{field_id}mapone, maptwomap_customer_custentity_skills

See Multi-Select Tables for detailed documentation.


Pricing Tables

TableLinksPurposeKey Columns
ItemPriceItem → PricesBase pricingitem, pricelevel, currency, unitprice
PricingGroupItem → Pricing GroupsGroup-based pricingitem, pricinggroup
CustomerPricingCustomer → Item PricesCustomer-specificcustomer, item, price

Example: Item with All Price Levels

-- All prices for an item across levels and currencies
SELECT
i.itemid,
i.displayname,
BUILTIN.DF(ip.currency) AS currency,
BUILTIN.DF(ip.pricelevel) AS price_level,
ip.unitprice
FROM Item i
INNER JOIN ItemPrice ip ON ip.item = i.id
WHERE i.id = 500
ORDER BY ip.currency, ip.pricelevel

Billing/Revenue Tables

TableLinksPurposeKey Columns
BillingScheduleTransaction → BillingBilling milestonestransaction, billdate, billamount
RevenueRecognitionScheduleTransaction → RevenueRev rec schedulestransaction, scheduledate, amount

Quick Reference: Finding Junction Tables

Common Patterns

-- Transaction to lines
TransactionLine, TransactionAccountingLine, InventoryAssignment

-- Transaction to transaction
NextTransactionLineLink, PreviousTransactionLineLink

-- Record to addresses
EntityAddress, Address (joined via addressbook)

-- Record to files
MessageFile, ItemImage (name → File.name)

-- Record to history
SystemNote (recordid + recordtype)

-- Multi-select fields
map_{record}_{field_id}

Discovery Methods

  1. Records Catalog: Setup → Records Catalog → Search record type
  2. SuiteQL Query Tool: Tables Reference feature
  3. Tim Dietrich Reference: ~800 tables documented at timdietrich.me

Common Join Patterns

One-to-Many (Header → Lines)

FROM {header_table} h
INNER JOIN {line_table} l ON l.{header_fk} = h.id

Many-to-Many (via Mapping)

FROM {table1} t1
INNER JOIN map_{table1}_{field} m ON m.mapone = t1.id
INNER JOIN {table2} t2 ON t2.id = m.maptwo

Hierarchical (Self-Join)

FROM {table} child
LEFT JOIN {table} parent ON parent.id = child.{parent_fk}

Audit (Record → History)

FROM {record_table} r
INNER JOIN SystemNote sn ON sn.recordid = r.id
AND sn.recordtype = {type_id}

See Also