SuiteQL Customer Address Tables Explained
Understand Customer, CustomerAddressBook and CustomerAddressBookEntityAddress and join them correctly in SuiteQL.
NetSuite customer addresses are split across a customer record, an address-book entry and an address-value record. A useful mental model is:
Customer
-> CustomerAddressBook
-> CustomerAddressBookEntityAddress
Each table has a different responsibility.
Customer
This is the owning entity:
customer.id
customer.entityid
Joining directly from the customer gives the account or entity information, not the street-address fields.
CustomerAddressBook
This represents an entry in the customer’s address list. It contains relationship-level values such as:
customeraddressbook.id
customeraddressbook.entity
customeraddressbook.label
customeraddressbook.defaultbilling
customeraddressbook.defaultshipping
customeraddressbook.isresidential
customeraddressbook.addressbookaddress
Use its id when you need to identify a particular address-book row. The label is editable display text and is not a reliable unique key.
CustomerAddressBookEntityAddress
This contains the address values reached through addressbookaddress:
customeraddressbookentityaddress.addr1
customeraddressbookentityaddress.addr2
customeraddressbookentityaddress.addr3
customeraddressbookentityaddress.city
customeraddressbookentityaddress.state
customeraddressbookentityaddress.zip
customeraddressbookentityaddress.country
Join it through its key:
LEFT JOIN customeraddressbookentityaddress address_value
ON address_value.nkey = customeraddressbook.addressbookaddress
Complete join example
SELECT
customer.id AS customer_id,
customer.entityid,
address_book.id AS address_book_id,
address_book.label,
address_book.defaultbilling,
address_book.defaultshipping,
address_value.addr1,
address_value.addr2,
address_value.city,
address_value.state,
address_value.zip,
address_value.country
FROM customer
LEFT JOIN customeraddressbook address_book
ON address_book.entity = customer.id
LEFT JOIN customeraddressbookentityaddress address_value
ON address_value.nkey = address_book.addressbookaddress
The LEFT JOINs retain customers without an address. Change them to inner joins when an address is mandatory for the result.
Why field discovery matters
Available records and fields can vary with the execution role and account features. Use the Records Catalog with the same role used by the script or integration, then test a small query before building the full export.
When diagnosing a join, select the relationship keys:
address_book.entity
address_book.addressbookaddress
address_value.nkey
Seeing those values makes a broken join much easier to distinguish from a missing or restricted address.