Skip to main content

Introduction to SuiteQL

SuiteQL is NetSuite's SQL-like query language that provides powerful, flexible data retrieval capabilities using familiar SQL syntax.


What is SuiteQL?​

SuiteQL allows you to query NetSuite data using standard SQL syntax instead of the proprietary N/search API. It provides:

  • Familiar SQL syntax - SELECT, FROM, WHERE, JOIN, GROUP BY
  • Better performance - Optimized for complex queries
  • More flexibility - Advanced operations not available in N/search
  • Analytics tables - Access to pre-joined, flattened data views

Where Can You Use SuiteQL?​

MethodUse Case
N/query moduleSuiteScript automation, Suitelets, scheduled scripts
REST APIExternal integrations, third-party applications
Analytics WorkbookInteractive reporting, dashboards

SuiteQL vs N/search: When to Use Each​

Quick Comparison​

FeatureSuiteQLN/search
SyntaxSQL (familiar)NetSuite-specific API
JoinsExplicit SQL JOINsAutomatic via relationships
Complex queriesExcellentLimited
Window functionsYesNo
CTEs (WITH clause)YesNo
UNION operationsYesNo
Learning curveEasy (if you know SQL)Steeper
UI BuilderLimitedSaved Search UI

When to Use Which​

NeedUse
Complex multi-table JOINsSuiteQL
Window functions (ROW_NUMBER, RANK)SuiteQL
UNION to combine result setsSuiteQL
CTEs for readable complex queriesSuiteQL
Simple record lookupsN/search
Saved Search UI neededN/search
Formula fields with NS functionsN/search

Use SuiteQL When:​

  • You need complex multi-table JOINs
  • You want window functions (ROW_NUMBER, RANK, etc.)
  • You need UNION to combine result sets
  • You're comfortable with SQL
  • You want CTEs for readable complex queries

Use N/search When:​

  • Simple record lookups
  • You need the Saved Search UI
  • Formula fields with NetSuite-specific functions
  • You want automatic join handling
  • You need to save and share searches with users

Basic Syntax Overview​

Simple Query Structure​

SELECT column1, column2, column3
FROM table_name
WHERE condition
ORDER BY column1
LIMIT 100

Real NetSuite Example​

-- Get active customers with their credit limit
SELECT
id,
companyname,
email,
creditlimit
FROM
customer
WHERE
isinactive = 'F'
AND creditlimit > 0
ORDER BY
creditlimit DESC
LIMIT 50

Understanding Table Names​

NetSuite tables use record type names in lowercase:

Record TypeTable Name
Customercustomer
Sales Ordertransaction (with type filter)
Invoicetransaction (with type filter)
Itemitem
Employeeemployee
Vendorvendor
Custom Recordcustomrecord_yourrecordid

Your First SuiteQL Query​

Step 1: Simple Customer List​

-- Most basic query: list all customers
SELECT id, companyname
FROM customer
LIMIT 10

Result:

idcompanyname
1Acme Corporation
2Global Industries
3Tech Solutions

Step 2: Add Filtering​

-- Active customers only
SELECT id, companyname, email
FROM customer
WHERE isinactive = 'F'
LIMIT 10

Step 3: Add Sorting​

-- Active customers sorted by name
SELECT id, companyname, email
FROM customer
WHERE isinactive = 'F'
ORDER BY companyname ASC
LIMIT 10

Step 4: Use in SuiteScript​

/**
* @NApiVersion 2.1
* @NScriptType Suitelet
*/
define(['N/query'], (query) => {

const onRequest = (context) => {
// Run SuiteQL query
const results = query.runSuiteQL({
query: `
SELECT id, companyname, email
FROM customer
WHERE isinactive = 'F'
ORDER BY companyname
LIMIT 10
`
}).asMappedResults();

// Results is an array of objects
results.forEach(customer => {
log.debug('Customer', customer.companyname);
});
};

return { onRequest };
});

Finding Table and Column Names​

Method 1: Records Catalog​

  1. Go to Setup > Records Catalog
  2. Search for record type
  3. View available fields and their IDs

Method 2: Analytics Browser​

  1. Go to Analytics > Analytics Browser
  2. Browse tables and columns
  3. See data types and relationships

Method 3: Schema Query​

-- List all columns in customer table
SELECT *
FROM customer
WHERE 1 = 0 -- Returns no data, just schema

Common Record Types and Tables​

Transaction Tables​

TransactionType ValueExample Filter
Sales OrderSalesOrdtype = 'SalesOrd'
InvoiceCustInvctype = 'CustInvc'
Purchase OrderPurchOrdtype = 'PurchOrd'
Vendor BillVendBilltype = 'VendBill'
Cash SaleCashSaletype = 'CashSale'
Journal EntryJournaltype = 'Journal'

Entity Tables​

EntityTable Name
Customercustomer
Vendorvendor
Employeeemployee
Contactcontact
Partnerpartner

Item Tables​

Item TypeTable
All Itemsitem
Inventoryitem (with type filter)
Serviceitem (with type filter)
Assemblyitem (with type filter)

Query Best Practices​

Do's​

-- DO: Select only needed columns
SELECT id, companyname, creditlimit
FROM customer

-- DO: Use LIMIT for testing
SELECT * FROM customer LIMIT 10

-- DO: Use parameterized queries in SuiteScript
query.runSuiteQL({
query: 'SELECT * FROM customer WHERE id = ?',
params: [customerId]
});

Don'ts​

-- DON'T: Select all columns in production
SELECT * FROM transaction -- Slow!

-- DON'T: No LIMIT on large tables
SELECT id FROM transactionline -- Could return millions

-- DON'T: String concatenation for parameters (SQL injection risk!)
query: 'SELECT * FROM customer WHERE id = ' + customerId -- WRONG!

Next Steps​

Now that you understand the basics, continue learning:

  1. Operators & Functions - Filtering and data manipulation
  2. Joins - Combining data from multiple tables
  3. Aggregation - GROUP BY and aggregate functions
  4. N/query Module - Full SuiteScript integration

Quick Reference Card​

-- Basic template
SELECT columns
FROM table
WHERE conditions
GROUP BY columns
HAVING group_conditions
ORDER BY columns
LIMIT n OFFSET m

-- Common patterns
WHERE field = 'value' -- Exact match
WHERE field LIKE 'A%' -- Starts with A
WHERE field IN ('A', 'B', 'C') -- Multiple values
WHERE field BETWEEN 1 AND 100 -- Range
WHERE field IS NOT NULL -- Not empty