SQL Query

MongoDB? SQL? Why not both. SQL Query makes it possible to use SQL to query MongoDB.

Jump ahead to view the list of supported SQL expressions and joins.

Open SQL Query - Shift + Ctrl + L (Shift + ⌘+ L)
Execute SQL statement at cursor - F5
Open existing SQL file - Ctrl + O (⌘+ O)
Save current SQL Query - Ctrl + S (⌘+ S)
Save SQL Query as - Shift + Ctrl + S (Shift + ⌘+ S)

Basics

There are three ways to open SQL Query:


Button

Click on the SQL button on the global toolbar

Right-click

Right-click on a collection and choose Open SQL

Hotkey

Use Shift + Ctrl + L (Shift + ⌘+ L)

SQL Query has two main areas: the Editor where queries are written, and the Result Tab where query results are displayed.

The other tabs SQL Query, Query Code and Explain will be covered later in the tutorial.

Learn more about the three ways to view results (Table, Tree, and JSON view).

Execute SQL queries

A SQL statement can be executed in three ways:

Button

Click on the Execute SQL statement at cursor (play) button

Right-click

Place the cursor on the desired query, right-click, and choose Execute SQL statement at cursor

Hotkey

Press F5 to execute SQL statement at cursor

View the executed SQL query

The SQL Query tab shows which SQL query was executed at cursor.

Why is this useful?

It confirms the query that was actually run, especially in the case of a SQL batch which can contain multiple queries.

In the screenshot above, only the first query appears underneath the SQL Query tab because it is the SQL statement executed at cursor.

Edit results inline

Editing documents and data in the SQL view in Studio 3T is based on a ‘search and edit’ paradigm.

That is, rather than have to search for the documents you want to edit and then issue separate UPDATE, DELETE or INSERT commands, you can simply edit the documents directly inline.

To edit a particular field or value in a document, simply double-click on it and a type-specific editor for that value will be activated.

Pressing ‘Enter’ will write the new value to the database, while pressing ‘Esc’ will return the previous value and exit the editor.

Read the full documentation on In-Place Editing here.

Read-only mode

If you would rather that results were not directly editable, say perhaps on a production database, you can enable read-only mode in which all editors are disabled and data and documents cannot be edited inline.

Read-only mode can be activated dynamically by clicking on the padlock icon in the Results Tab. Whether read-only mode is activated by default or not can be configured under Preferences.

The Results Tab is part of the greater Collections Tab, the starting point for all Studio 3T data exploration.

Open and save SQL queries

Open and save SQL queries easily in Studio 3T

To save the current SQL query as a .sql file, click on the Save icon. Alternatively, click on the arrow next to it to find the Save As function.

To open existing .sql files, click on the folder icon.

Fancy dark mode? Enable it following these steps.

Generate JavaScript, Java, Python, C# and PHP code from SQL queries

Query Code is a feature available in Studio 3T that converts SQL queries into JavaScript (Node.js), Java (2.x and 3.x driver API), Python, C#, PHP, and the mongo shell language.

To see a SQL query’s equivalent code:

  1. Execute the SQL query
  2. Click on the Query Code tab
  3. Choose the target language

View the equivalent MongoDB query

To view how a SQL query is written in MongoDB query syntax:

  1. Click on the Query Code tab
  2. Choose mongo shell

Older versions of Studio 3T supported a MongoDB Query tab prior to Query Code. Download the latest Studio 3T version here.

Explain data for the query

You can also click on the Explain tab and this will show expected performance data of executing the query.

A full explanation of the explain data is beyond the scope of this tutorial, but please refer to the MongoDB manual for details.

Supported SQL expressions

To query MongoDB with SQL, Studio 3T supports many SQL expressions, functions, and ways to express query criteria. This tutorial uses the data set Customers to illustrate examples.

Download the Customers collection here and import it into Studio 3T to follow along the tutorial.

SELECT *

Studio 3T automatically generates a basic SELECT * query by default. This retrieves all of the documents in a collection, similar to selecting all the rows of a table in an SQL database.

The SQL query

select *
from Customers;

shows all documents and fields within the Customers collection.

Accessing embedded fields using dotted names

Some fields may be contained within an embedded document. You can access such fields using dot notation.

In the Customers collection, the field address has four embedded fields: street, city, state, and zip_code.

To find customers living in the city Berlin, run the following SQL query:

select *
from Customers
where address.city = 'Berlin';

The other embedded fields would be then referenced as address.street, address.state, and address.zip_code, respectively.

Be aware, however, of the differences when quoting names and string values.

Quoting names and string values

String values in a SQL query in Studio 3T should always be single-quoted.

where address.city = 'Berlin'

Names, including collection names and field names, both dotted and not, may be quoted using back-ticks, square brackets, and double-quotes.

For example, we could write:

where `address.city` = 'Berlin'

or:

where [address.city] = 'Berlin'

or:

where "address.city" = 'Berlin'

When writing SQL queries in Studio 3T, the rules are simple:

  • Use single-quotes for string values
  • Use back-ticks, square brackets, or double-quotes for names

Projection

To see only specific fields (for example, to display only the first name, last name, city, and number of transactions), run the query:

select first, last, address.city, transactions
from Customers;

Comparison operators

Studio 3T supports the standard SQL comparison operators:  =<><<=>=, or >.

To find customers with less than twenty transactions, execute the SQL query:

select *
from Customers
where transactions < 20;

AND or OR

Expressions can be combined using AND or OR:

select *
from Customers
where transactions < 20
and address.city = 'Berlin'
or address.city = 'New York'
;

ORDER BY

Results can be ordered or sorted by specifying an ORDER BY clause.

By default, ORDER BY sorts results in ascending order, which is the number of transactions in this example:

select *
from Customers
order by transactions;

Add desc to order customers by number of transactions in descending order:

select *
from Customers
order by transactions desc;

Match Boolean values

Use the Boolean values true and false when querying Boolean fields in a MongoDB document, for example:

select *
from docsWithBoolsCollection
where myBoolField = true;

Some dialects of SQL use the integer values 1 and 0 to represent the Boolean values true and false respectively.

MongoDB collections are schema-free, so there’s no schema to indicate that a particular field is of Boolean type. Therefore, a value of 1 really means true in that case.

No match will occur when an attempt to match a field with a Boolean value against 0 or 1 is made. With Studio 3T, remember to use true and false when matching Boolean values.

In MongoDB, integer and Boolean values are of distinct types.

GROUP BY

GROUP BY groups a result set by a particular field, and is often used with other aggregate functions like COUNT, SUM, AVG, MIN and MAX.

For example, to group customers by city, use the following SQL query:

select address.city
from Customers
group by address.city;

The results won’t display the count of customers per city, but the list of unique cities represented in the data.

COUNT

COUNT shows the actual count of documents that match the query criteria.

The following SQL query shows the number of customers per city in ascending order:

select count(*), address.city
from Customers
group by address.city
order by count(*);

SUM

SUM shows the total sum of values of a numeric field.

To see the total number of transactions, execute the query:

select sum(transactions)
from Customers;

AVG

AVG displays the average value of a numeric field across a collection.

The average number of transactions is shown with the query:

select avg(transactions)
from Customers;

MIN

MIN shows the smallest value of a particular field across a collection.

Run the following query to see the lowest number of transactions associated with a single customer:

select min(transactions)
from Customers;

MAX

MAX shows the largest value of a particular field across a collection.

The SQL query

select max(transactions)
from Customers;

shows the highest number of transactions associated with a single customer.

LIMIT

The LIMIT clause limits the number of documents returned in a result set.

Results can be limited to only show 12 customers with the query:

select *
from Customers
limit 12;

Studio 3T shows 50 documents by default.

OFFSET

The OFFSET clause skips a certain number of documents in the result set.

To skip the first 25 customers while still limiting the results to 12, use the query:

select *
from Customers
limit 12
offset 25;

LIKE

The LIKE operator is stated to find a pattern in the values of a field, often used with wildcards.

Wildcards

Wildcard characters % and _ are used to substitute characters in a string to find matches.

For example:

select *
from Customers
where address.city like '%New%';

will show customers whose cities contain the substring “New”, e.g. Newark, New York, New Orleans.

To show customers whose cities start with the substring “Lon”, the wildcard character % is only placed at the end:

select *
from Customers
where address.city like 'Lon%';

To find customers whose cities start with any letter but ends with “aris”, the wildcard _is used:

select *
from Customers
where address.city like '_aris';

To find customers whose cities that start with any two letters but end with “ris”, simply add an additional _:

select *
from Customers
where address.city like '__ris';

IN

The IN operator can be used to see if a customer is a member of a set.

select *
from Customers
where address.city in ('Berlin', 'New York', 'Wichita');

BETWEEN and NOT BETWEEN

The BETWEEN operator shows if a value lies within a range. The opposite is the operator NOT BETWEEN.

The query to find customers with transactions between 70 to 100 is:

select *
from Customers
where transactions between 70 and 100;

While the query to show customers whose cities start with a letter not in between B and D is:

select *
from Customers
where address.city not between 'B' and 'D';

Numeric values should not be in quotes, as in the example above.

Special BSON Data Types

MongoDB supports special BSON data types, which in the MongoDB shell are represented by ObjectId, NumberDecimal and BinData, for example.

To query values of these types, write out the values as they would be written in the mongo shell:

select *
from specialBSONDataTypesCollection
where _id = ObjectId('16f319f52bead12669d02abc');

select *
from specialBSONDataTypesCollection
where aNumberDecimal = NumberDecimal('9876543210987654321.0');

select *
from specialBSONDataTypesCollection
where aBinDataField = BinData(0, 'QyHcug==');

ISODate values can also be queried this way, but as described in the section above, it can be more convenient to use the date function provided in the Studio 3T SQL tab to specify date values in various common, concise formats.

Ready to try SQL Query? Download the latest version of Studio 3T here.

Supported SQL joins

Studio 3T built upon MongoDB’s native join functionality and recently introduced support for inner joins and left joins in SQL Query.


Users can write SQL joins, then generate the equivalent mongo shell code, using the Query Code feature. They can then use this MongoDB “translation” to query any other appropriate MongoDB database, without additional support or libraries.

However, in doing so, there are one or two considerations to bear in mind, covered below.

Inner joins and left joins

To start, the syntax is simple. To perform an inner join:

select *
from collA
inner join collB on collA.field1 = collB.field2;

And for left joins:

select *
from collA
left join collB on collA.field1 = collB.field2;

Projections

Projections can be performed on the joined collections. These take the following form:

select collA.field1, collA.field3, collB.field2, collB.field4
from collA
inner join collB on collA.field1 = collB.field2;

Note that fields referenced in the projection must be qualified with the collection name, e.g. ‘collA.field1‘ and not just ‘field1‘.

While in a relational ‘schemaful’ setting, providing only the column (field) name would be sufficient if it were distinct to one of the tables, in the schemaless MongoDB setting, there’s no schema to indicate to which collection a particular field belongs, so the field name must be qualified explicitly with its collection.

By the same token, note that while wildcards such as ‘select * …‘ are permitted, ‘select collA.* …‘ are not.

Multiple joins

Multiple joins are supported, simply write queries such as:

select *
from collA
inner join collB on collA.field1 = collB.field2
left join collC on collB.field3 = collC.field1;

The order in which joins are processed is the same in which they are written, and a join condition must only reference collections to the left of it.

Extended queries

And of course, SQL aggregate functions, group by, having, etc. can all be applied to the joined collections, too:

select collA.field3, collB.field3, count(*)
from collA
inner join collB on collA.field1 = collB.field2
where collA.date > date('2018-01-01')
group by collA.field3, collB.field3
having count(*) > 250
order by collA.field3, collB.field3
limit 1
offset 1;

Joining a collection to itself

A collection can be joined to itself through the use of aliases, for example:

select *
from collA as child
inner join collA as parent on parent._id = child.parentId;

Note that after a collection has been aliased, all references to its fields must use that alias and not the original name.

Cross joins

Studio 3T also supports cross joins, like:

select *
from collA
cross join collB;

or:

select *
from collA, collB;

Take care however, cross join queries can quickly become expensive to run as the number of documents in the collections grow.

Interested in learning more about joins in MongoDB? Read our MongoDB tutorial, How to Create MongoDB Joins with SQL.

Supported date and time formats

Studio 3T allows dates and times to be expressed in these formats:

select *
from dates_example
where d > date('2017-03-22T00:00:00.000Z');

select *
from dates_example
where d > date('2017-03-22T00:00:00.000+0000');

select *
from dates_example
where d > date('2017-03-22T00:00:00.000');

select *
from dates_example
where d > date('2017-03-22T00:00:00');

select *
from dates_example
where d > date('2017-03-22T00:00');

select *
from dates_example
where d > date('2017-03-22 00:00:00.000Z');

select *
from dates_example
where d > date('2017-03-22 00:00:00.000+0000');

select *
from dates_example
where d > date('2017-03-22 00:00:00.000');

select *
from dates_example
where d > date('2017-03-22 00:00:00');

select *
from dates_example
where d > date('2017-03-22 00:00');

select *
from dates_example
where d > date('20170322T000000.000Z');

select *
from dates_example
where d > date('20170322T000000.000+0000');

select *
from dates_example
where d > date('20170322T000000.000');

select *
from dates_example
where d > date('20170322T000000');

select *
from dates_example
where d > date('20170322T0000');

select *
from dates_example
where d > date(‘2017-03-22’);

select *
from dates_example
where d > date('20170322');

Want to start using SQL to query MongoDB? Download Studio 3T here, in case you haven’t yet. 


Take advantage of other Studio 3T features:

Updated on December 13, 2018

Was this article helpful?

Related Articles