CartoDB is a cloud-based GIS platform which provides data management, query, and visualization capabilities. CartoDB is based on Postgres/PostGIS in the backend, and one of the most exciting functions of this platform is the ability to pass spatial queries using PostGIS syntax via the URL and HTTP API.
To publish the data to CartoDB, you'll first need to establish an account. You can easily do this with the Google Single sign-in or create your own account with a username and password. CartoDB offers free accounts, which are usable for an unlimited amount time. You are limited to 50 MB of data storage and all the data published will be publically viewable. Once you've signed up, you can upload the layer produced in the previous section. Perform the following steps:
c3/data/output/channels.* and c3/data/output/toxic_channels.*, to prepare them for upload to CartoDB.c3/data/output/channels.zip and c3/data/output/toxic_channels.zip and add these to the map.
SQL is the lingua franca of database queries through which you can do anything from filtering to spatial operations to manipulating data on the database. There are slight differences in the way SQL works from one database system to the next one. The CartoDB SQL queries use valid Postgres/PostGIS syntax. For more information on Postgres/PostGIS SQL, check out the reference chapter in the manuals for Postgres (http://www.postgresql.org/docs/9.4/interactive/reference.html) for general functions and PostGIS (http://postgis.net/docs/manual-2.1/reference.html) for spatial functions.
There are a few different ways in which you can test your queries against CartoDB—each involving a different ease of input and producing a different result type.
Our SQL query only requires one parameter that we do not know ahead of time: the coordinates of the user-selected click location. To simulate this interaction with QGIS and generate a coordinate pair, we will use the Coordinate Capture plugin. Perform the following steps:


Now, we will return to CartoDB in a web browser to run our first test.
While this method is probably the most straightforward in terms of data entry, it is limited to producing results via the map. There are no text results produced besides errors, which limits your ability to test and debug. Perform the following steps:
Recall that we generated test coordinates to pass with the Coordinate Capture plugin in the last step. Enter the following into the SQL area. This query will select all the fields from toxic_channels as expressed with the wildcard symbol (*) using various subqueries, joins, and spatial operations. The end result will show all the toxic sites that are upstream from the clicked point in its basin (code in c3/data/original/query1.sql). Execute the following code:
SELECT toxic_channels.* FROM toxic_channels
INNER JOIN channels
ON toxic_channels.join_BASIN = channels.basin
WHERE toxic_channels.join_order <
(SELECT channels._order
FROM channels
WHERE
st_distance(the_geom, ST_GeomFromText
('POINT(-75.56111 39.72583)',4326))
IN (SELECT MIN(st_distance(the_geom,
ST_GeomFromText('POINT(-75.56111 39.72583)',4326)))
FROM channels x))
AND toxic_channels.join_basin =
(SELECT channels.basin
FROM channels
WHERE
st_distance(the_geom, ST_GeomFromText
('POINT(-75.56111 39.72583)',4326))
IN (SELECT MIN(st_distance(the_geom,
ST_GeomFromText('POINT(-75.56111 39.72583)',4326)))
FROM channels x))
GROUP BY toxic_channels.cartodb_idIf the query runs successfully, you should see an output similar to the following image:

The following errors may confound the efforts to debug and test via the CartoDB SQL tab:
cartodb_id field so that it does not generate this error. However, this error does not typically affect the use through the API or URL parameters.the_geom column even though this column is not visible within your cartodb table, to map the result.Sometimes, the SQL input area is "sticky". If this happens, just "clear view".
Next, let's test the SQL from within QGIS using the QGIS CartoDB Plugin. Perform the following steps:
username.cartodb.com/*. You can find your API key by clicking on your avatar from your dashboard and selecting Your API keys.

The layer added from these steps will give you the location of the toxic sites upstream from the chosen coordinate. If you symbolized these locations with stars and streams according to their upstream/downstream rank, you would see something similar to the following image:

If you want to see the actual contents returned by a CartoDB SQL query in the JSON format, the best way to do so is by sending your SQL statement to the CartoDB SQL API endpoint at http://[YOURUSERNAME].cartodb.com/api/v2/sql. This can be useful to debug issues in interaction with your web application in particular.
The browser string uses an encoded URL, which substitutes character sequences for some special characters. For example, you could use a URL encoder/decoder, which is easily found on the Web, to produce such a string.
Use the following instructions to see the result JSON returned by CartoDB given a particular SQL query. The URL string is also contained in c3/data/original/url_query1.txt.
[YOURUSERNAME] with your CartoDB user name and [YOURAPIKEY] with your API key:http://[YOURUSERNAME].cartodb.com/api/v2/sql?q=%20SELECT%20toxic_channels.*%20FROM%20toxic_channels%20INNER%20JOIN%20channels%20ON%20toxic_channels.join_BASIN%20=%20channels.basin%20WHERE%20toxic_channels.join_order%20%3C%20(SELECT%20channels._order%20FROM%20channels%20WHERE%20st_distance(the_geom,%20ST_GeomFromText%20(%27POINT(-75.56111%2039.72583)%27,4326))%20IN%20(SELECT%20MIN(st_distance(the_geom,%20ST_GeomFromText(%27POINT(-75.56111%2039.72583)%27,4326)))%20FROM%20channels%20x))%20AND%20toxic_channels.join_basin%20=%20(SELECT%20channels.basin%20FROM%20channels%20WHERE%20st_distance(the_geom,%20ST_GeomFromText%20(%27POINT(-75.56111%2039.72583)%27,4326))%20IN%20(SELECT%20MIN(st_distance(the_geom,%20ST_GeomFromText(%27POINT(-75.56111%2039.72583)%27,4326)))%20FROM%20channels%20x))%20GROUP%20BY%20toxic_channels.cartodb_id%20&api_key=[YOURAPIKEY]
{"rows":[{"the_geom":"0101000020E610000056099A6A64E352C0B23A9C05D4E84340","id":13,"join_segme":1786,"join_node_":1897,"join_nod_1":1886,"join_basin":98,"join_order":2,"join_ord_1":6,"join_lengt":1890.6533221,"distance":150.739169156001,"cartodb_id":14,"created_at":"2015-05-06T21:52:52Z","updated_at":"2015-05-06T21:52:52Z","the_geom_webmercator":"0101000020110F00000B1E9E3DB30A60C18DCB53943D765241"},{"the_geom":"0101000020E61000001144805EA1E652C0ECE7F94B65E64340","id":3,"join_segme":1710,"join_node_":1819,"join_nod_1":1841,"join_basin":98,"join_order":1,"join_ord_1":5,"join_lengt":769.46323073,"distance":50.1031572450681,"cartodb_id":4,"created_at":"2015-05-06T21:52:52Z","updated_at":"2015-05-06T21:52:52Z","the_geom_webmercator":"0101000020110F0000181D4045730D60C1F35490178D735241"},{"the_geom":"0101000020E61000009449A70ACFF052C0F3916D0D41D34340","id":17,"join_segme":1098,"join_node_":1188,"join_nod_1":1191,"join_basin":98,"join_order":1,"join_ord_1":5,"join_lengt":1320.8328273,"distance":260.02935238833,"cartodb_id":18,"created_at":"2015-05-06T21:52:52Z","updated_at":"2015-05-06T21:52:52Z","the_geom_webmercator":"0101000020110F00008167DA44181660C117FA8EFC695E5241"},{"the_geom":"0101000020E6100000DD53F65225EA52C0966E1B86B1E64340","id":19,"join_segme":1728,"join_node_":1839,"join_nod_1":1826,"join_basin":98,"join_order":1,"join_ord_1":5,"join_lengt":489.2571289,"distance":201.8453893386,"cartodb_id":20,"created_at":"2015-05-06T21:52:52Z","updated_at":"2015-05-06T21:52:52Z","the_geom_webmercator":"0101000020110F00009D303E9A6F1060C1BAD6D85BE1735241"},{"the_geom":"0101000020E61000008868F447FAE452C02218260DC0E94340","id":12,"join_segme":1801,"join_node_":1913,"join_nod_1":1899,"join_basin":98,"join_order":2,"join_ord_1":6,"join_lengt":539.82994246,"distance":232.424790511141,"cartodb_id":13,"created_at":"2015-05-06T21:52:52Z","updated_at":"2015-05-06T21:52:52Z","the_geom_webmercator":"0101000020110F00003BC511F10B0C60C1D801919542775241"},{"the_geom":"0101000020E6100000A2EE318E20EF52C0A874919E9BD44340","id":16,"join_segme":1151,"join_node_":1243,"join_nod_1":1195,"join_basin":98,"join_order":1,"join_ord_1":5,"join_lengt":1585.6022332,"distance":48.7125304167275,"cartodb_id":17,"created_at":"2015-05-06T21:52:52Z","updated_at":"2015-05-06T21:52:52Z","the_geom_webmercator":"0101000020110F000055062CA8AA1460C19A29734CE85F5241"},{"the_geom":"0101000020E610000043356AB28DEE52C090391E3073DF4340","id":21,"join_segme":1548,"join_node_":1650,"join_nod_1":1633,"join_basin":98,"join_order":3,"join_ord_1":7,"join_lengt":893.68816603,"distance":733.948566072529,"cartodb_id":22,"created_at":"2015-05-06T21:52:52Z","updated_at":"2015-05-06T21:52:52Z","the_geom_webmercator":"0101000020110F0000F46510EE2D1460C18C0E2241E06B5241"},{"the_geom":"0101000020E61000009B543F2277EA52C0F3615A0BD1D54340","id":1,"join_segme":1198,"join_node_":1292,"join_nod_1":1293,"join_basin":98,"join_order":1,"join_ord_1":5,"join_lengt":746.7496066,"distance":123.258432999702,"cartodb_id":2,"created_at":"2015-05-06T21:52:52Z","updated_at":"2015-05-06T21:52:52Z","the_geom_webmercator":"0101000020110F0000CFB06115B51060C1B715F2AF3D615241"},{"the_geom":"0101000020E610000056AEF2E2D0EE52C0305E947734D94340","id":9,"join_segme":1336,"join_node_":1432,"join_nod_1":1391,"join_basin":98,"join_order":1,"join_ord_1":5,"join_lengt":1143.9037155,"distance":281.665088681164,"cartodb_id":10,"created_at":"2015-05-06T21:52:52Z","updated_at":"2015-05-06T21:52:52Z","the_geom_webmercator":"0101000020110F0000D8727BFE661460C1F269C8F6FA645241"}],"time":0.029,"fields":{"the_geom":{"type":"geometry"},"id":{"type":"number"},"join_segme":{"type":"number"},"join_node_":{"type":"number"},"join_nod_1":{"type":"number"},"join_basin":{"type":"number"},"join_order":{"type":"number"},"join_ord_1":{"type":"number"},"join_lengt":{"type":"number"},"distance":{"type":"number"},"cartodb_id":{"type":"number"},"created_at":{"type":"date"},"updated_at":{"type":"date"},"the_geom_webmercator":{"type":"geometry"}},"total_rows":9}