Docs for ‘QGIS 2.18’. Visit http://docs.qgis.org/2.14 for QGIS 2.14 docs and translations.
A special kind of vector layer allows you to define a layer as the result of an advanced query, using the SQL language on any number of other vector layers that QGIS is able to open. These layers are called virtual layers: they do not carry data by themselves and can be seen as views to other layers.
Open the virtual layer creation dialog by clicking on Add Virtual Layer in the Layer menu or from the corresponding toolbar.
The dialog allows you to specify a Layer name and a SQL Query. The query can use the name (or id) of loaded vector layers as tables, as well as their fields’ name as columns.
For example, if you have a layer called airports, you can create a new virtual layer called public_airports with an SQL query like:
SELECT *
FROM airports
WHERE USE = "Civilian/Public"
The SQL query will be executed, whatever the underlying provider of the airports layer is and even if this provider does not directly support SQL queries.
Joins and complex queries can also be created simply by directly using the names of the layers that are to be joined.
Note
It’s also possible to create virtual layers using the SQL window of DB Manager Plugin.
Besides the vector layers available in the map canvas, the user can add layers to the Embedded layers list, which he can use in queries without the need to have them showing in the map canvas or Layers panel.
To embed a layer, click Add and provide the Local name, Provider, Encoding and the path to the Source.
The Import button allows adding layers loaded in the map canvas into the Embedded layers list. This allows to later remove those layers from the Layers panel without breaking any existent query.
The underlying engine uses SQLite and Spatialite to operate.
It means you can use all of the SQL your local installation of SQLite understands.
Functions from SQLite and spatial functions from Spatialite can also be used in a virtual layer query. For instance, creating a point layer out of an attribute-only layer can be done with a query similar to:
SELECT id, MakePoint(x, y, 4326) as geometry
FROM coordinates
Functions of QGIS expressions can also be used in a virtual layer query.
To refer the geometry column of a layer, use the name geometry.
Contrary to a pure SQL query, all the fields of a virtual layer query must be named. Don’t forget to use the as keyword to name your columns if they are the result of a computation or function call.
With default parameters set, the virtual layer engine will try its best to detect the type of the different columns of the query, including the type of the geometry column if one is present.
This is done by introspecting the query when possible or by fetching the first row of the query (LIMIT 1) at last resort. Fetching the first row of the result just to create the layer may be undesirable for performance reasons.
The creation dialog allows to specify different parameters:
The virtual layer engine tries to determine the type of each column of the query. If it fails, the first row of the query is fetched to determine column types.
The type of a particular column can be specified directly in the query by using some special comments.
The syntax is the following: /*:type*/. It has to be placed just after the name of a column. type can be either int for integers, real for floating point numbers or text.
For instance:
SELECT id+1 as nid /*:int*/
FROM table
The type and coordinate reference system of the geometry column can also be set thanks to special comments with the following syntax /*:gtype:srid*/ where gtype is the geometry type (point, linestring, polygon, multipoint, multilinestring or multipolygon) and srid an integer representing the EPSG code of a coordinate reference system.
When requesting a layer through a virtual layer, indexes of this source layer will be used in the following ways:
A specific syntax exists to handle spatial predicates in requests and triggers the use of a spatial index: a hidden column named _search_frame_ exists for each virtual layer. This column can be compared for equality to a bounding box. Example:
SELECT *
FROM vtab
WHERE _search_frame_=BuildMbr(-2.10,49.38,-1.3,49.99,4326)
Spatial binary predicates like ST_Intersects are significantly sped up when used in conjunction with this spatial index syntax.