Netezza SQL Training

Course Number: NET102-W

Duration: 3 days

Format: Live, online

Overview

In this training class, students will learn the Netezza SQL starting at the most basic level and going to the most advanced level with many examples.

Objectives

  • Gain a deeper knowledge and understanding of the Netezza SQL and how to write it.

Attendee Setup Instructions

For details about what is required when attending this class, please refer to the these instructions (will open in a seperate browser window).

Outline

  • Basic SQL Functions
    • Introduction
    • SELECT * (All Columns) in a Table
    • Fully Qualifying a Database, Schema and Table
    • SELECT Specific Columns in a Table
    • Commas in the Front or Back?
    • Using Good Form
    • Using the Best Form for Writing SQL
    • Place your Commas in front for better Debugging Capabilities
    • Sort the Data with the ORDER BY Keyword
    • ORDER BY Defaults to Ascending
    • Use the Name or the Number in your ORDER BY Statement
    • Two Examples of ORDER BY using Different Techniques
    • Changing the ORDER BY to Descending Order
    • NULL Values sort First in Ascending Mode (Default)
    • NULL Values sort Last in Descending Mode (DESC)
    • Major Sort vs. Minor Sorts
    • Multiple Sort Keys using Names vs. Numbers
    • Sorts are Alphabetical, NOT Logical
    • Using A CASE Statement to Sort Logically
    • How to ALIAS a Column Name
    • A Missing Comma can by Mistake become an Alias
    • Using Limit to bring back a Sample
    • Comments using Double Dashes are Single Line Comments
    • Comments for Multi-Lines
    • Comments for Multi-Lines as Double Dashes Per Line
    • A Great Technique for Comments to Look for SQL Errors
  • The WHERE Clause
    • The WHERE Clause limits Returning Rows
    • Using a Column ALIAS throughout the SQL
    • Double Quoted Aliases are for Reserved Words and Spaces
    • Character Data needs Single Quotes in the WHERE Clause
    • Character Data needs Single Quotes, but Numbers Don't
    • NULL means UNKNOWN DATA so Equal (=) won't Work
    • Use IS NULL or IS NOT NULL when dealing with NULLs
    • NULL is UNKNOWN DATA so NOT Equal won't Work
    • Use IS NULL or IS NOT NULL when dealing with NULLs
    • Using Greater Than or Equal To (>=)
    • AND in the WHERE Clause
    • Troubleshooting AND
    • OR in the WHERE Clause
    • Troubleshooting OR
    • OR must utilize the Column Name Each Time
    • Troubleshooting Character Data
    • Using Different Columns in an AND Statement
    • What is the Order of Precedence?
    • Using Parentheses to change the Order of Precedence
    • Using an IN List in place of OR
    • The IN List is an Excellent Technique
    • IN List vs. OR brings the same Results
    • Using a NOT IN List
    • A Technique for Handling Nulls with a NOT IN List
    • A Better Technique for Handling Nulls with a NOT IN List
    • BETWEEN is Inclusive
    • BETWEEN Works for Character Data
    • LIKE uses Wildcards Percent '%' and Underscore '_'
    • LIKE command Underscore is Wildcard for one Character
    • LIKE Command Works Differently on Char Vs Varchar
    • Troubleshooting LIKE Command on Character Data
    • Introducing the TRIM Command
    • Numbers are Right Justified and Character Data is Left
    • An Example of Data with Left and Right Justification
    • A Visual of CHARACTER Data vs. VARCHAR Data
    • Use the TRIM command to remove spaces on CHAR Data
    • TRIM Eliminates Leading and Trailing Spaces
    • Escape Character in the LIKE Command changes Wildcards
    • Escape Characters Turn off Wildcards in the LIKE Command
  • Distinct Vs Group By
    • The Distinct Command
    • Distinct vs. GROUP BY
    • Rules of Thumb for DISTINCT Vs GROUP BY
  • Review
    • Testing Your Knowledge 1-7
  • Aggregation Function
    • The 3 Rules of Aggregation
    • There are Five Aggregates
    • Troubleshooting Aggregates
    • GROUP BY when Aggregates and Normal Columns Mix
    • GROUP BY delivers one row per Group
    • GROUP BY Dept_No or GROUP BY 1 the same thing
    • Aggregates and Derived Data
    • Limiting Rows and Improving Performance with WHERE
    • WHERE Clause in Aggregation limits unneeded Calculations
    • Keyword HAVING tests Aggregates after they are totaled
    • Keyword HAVING is like an Extra WHERE Clause for Totals
    • Getting the Average Values per Column
    • Average Values per Column For all Columns in a Table
    • Three types of Advanced Grouping
    • GROUP BY Grouping Sets
    • GROUP BY Rollup
    • GROUP BY Rollup Result Set
    • GROUP BY Cube
    • GROUP BY CUBE Result Set
    • GROUP BY CUBE Result Set
    • Testing Your Knowledge
    • Final Answer to Test Your Knowledge on Aggregates
  • Join Functions
    • A two-table join using Non-ANSI Syntax
    • A two-table join using Non-ANSI Syntax with Table Alias
    • Aliases and Fully Qualifying Columns
    • A two-table join using Non-ANSI Syntax
    • Both Queries have the same Results and Performance
    • LEFT OUTER JOIN
    • LEFT OUTER JOIN Example and Results
    • RIGHT OUTER JOIN
    • RIGHT OUTER JOIN Example and Results
    • FULL OUTER JOIN
    • FULL OUTER JOIN Example and Results
    • Which Tables are the Left and which are the Right?
    • INNER JOIN with Additional AND Clause
    • ANSI INNER JOIN with Additional AND Clause
    • ANSI INNER JOIN with Additional WHERE Clause
    • OUTER JOIN with Additional WHERE Clause
    • OUTER JOIN with Additional AND Clause
    • OUTER JOIN with Additional AND Clause Example
    • The DREADED Product Join
    • The DREADED Product Join
    • The Horrifying Cartesian product Join
    • The ANSI Cartesian Join will ERROR
    • The CROSS JOIN
    • The CROSS JOIN Answer Set
    • The Self Join
    • The Self Join with ANSI Syntax
    • How would you join these two tables?
    • How would you join these two tables? You can't….Yet!
    • An Associative Table is a Bridge that Joins Two Table
    • The 5-Table Join - Logical Insurance Model
    • The Nexus Query Chameleon Writes the SQL for Users
  • Date Functions
    • Date, Time, and Timestamp Keywords
    • Add or Subtract Days from a date
    • The to_char command
    • Conversion Functions
    • Conversion Function Templates
    • Conversion Function Templates Continued
    • Formatting a Date
    • A Summary of Math Operations on Dates
    • Using a Math Operation to find your Age in Years
    • Find What Day of the week you were born
    • The ADD_MONTHS Command
    • Using the ADD_MONTHS Command to Add 1-Year
    • Using the ADD_MONTHS Command to Add 5-Years
    • Date Related Functions
    • The EXTRACT Command
    • EXTRACT from DATES and TIME
    • EXTRACT with DATE and TIME Literals
    • EXTRACT of the Month on Aggregate Queries
    • A Side Title example with Reserved Words as an Alias
    • Implied Extract of Day, Month, and Year
    • DATE_PART Function
    • DATE_PART Function using an ALIAS
    • DATE_TRUNC Function
    • DATE_TRUNC Function using TIME
    • MONTHS_BETWEEN Function
    • MONTHS_BETWEEN Function in Action
    • ANSI TIME
    • ANSI TIMESTAMP
    • Netezza TIMESTAMP Function
    • Netezza TO_TIMESTAMP Function
    • Netezza NOW () Function
    • Netezza TIMEOFDAY Function
    • Netezza AGE Function
    • Time Zones
    • Setting Time Zones
    • Using Time Zones
    • Intervals for Date, Time, and Timestamp
    • Using Intervals
    • Troubleshooting the Basics of a Simple Interval
    • Interval Arithmetic Results
    • A Date Interval Example
    • A Time Interval Example
    • A - DATE Interval Example
    • A Complex Time Interval Example using CAST
    • A Complex Time Interval Example using CAST
    • The OVERLAPS Command
    • An OVERLAPS Example that Returns No Rows
    • The OVERLAPS Command using TIME
    • The OVERLAPS Command using a NULL Value
  • OLAP Functions
    • How ANSI Moving SUM Handles the Sort
    • Moving SUM every 3-rows Vs a Continuous Average
    • Partition by Resets an ANSI OLAP
    • The ANSI Moving Window is Current Row and Preceding
    • How ANSI Moving Average Handles the Sort
    • Moving Average every 3-rows Vs a Continuous Average
    • Partition by Resets an ANSI OLAP
    • Moving Difference using ANSI Syntax
    • Moving Difference using ANSI Syntax with Partition By
    • RANK using ANSI Syntax Defaults to Ascending Order
    • Getting RANK using ANSI Syntax to Sort in DESC Order
    • RANK () OVER and PARTITION BY
    • RANK () OVER and LIMIT
    • PERCENT_RANK () OVER
    • PERCENT_RANK () OVER with 14 rows in Calculation
    • PERCENT_RANK () OVER with 21 rows in Calculation
    • COUNT OVER for a Sequential Number
    • Troubleshooting COUNT OVER
    • The MAX OVER Command
    • MAX OVER with PARTITION BY Reset
    • Troubleshooting MAX OVER
    • The MIN OVER Command
    • Troubleshooting MIN OVER
    • The Row_Number Command
    • Standard Deviation Functions Using STDDEV / OVER
    • Standard Deviation Functions and STDDEV / OVER Syntax
    • STDDEV / OVER Example
    • Variance Functions Using VARIANCE / OVER
    • VARIANCE / OVER Syntax
    • Using VARIANCE with PARTITION BY Example
    • Using FIRST_VALUE and LAST_VALUE
    • Using FIRST_VALUE
    • Using LAST_VALUE
    • Using LAG and LEAD
    • Using LEAD
    • Using LEAD With and Offset of 2
    • Using LAG
    • Using LAG with an Offset of 2
  • Temporary Tables
    • There are Three Types of Temporary Tables
    • CREATING A Derived Table
    • Naming the Derived Table
    • Aliasing the Column Names in the Derived Table
    • Multiple Ways to Alias the Columns in a Derived Table
    • CREATING a Derived Table using the WITH Command
    • Naming the Derived Table Columns using WITH
    • The Same Derived Query shown Three Different Ways
    • Most Derived Tables Are Used To Join To Other Tables
    • Our Join Example with a Different Column Aliasing Style
    • Column Aliasing Can Default For Normal Columns
    • Our Join Example With the WITH Syntax
    • Clever Tricks on Aliasing Columns in a Derived Table
    • An Example of Two Derived Tables in a Single Query
    • Syntax for Creating A Temporary Table
    • Creating and Populating a Temporary Table
    • A Temporary Table in Action
    • A Temporary Table Can Be Used Again and Again
    • Alternative CREATE TEMPORARY TABLE Option
    • A CTAS Temp Table to Improve Zone Map Selectivity
    • Creating a Temp Table as a Cluster Based Table (CBT)
    • What Are External Tables?
    • External Tables Data Loading Formats
    • External Table Log Files
    • External Table Syntax
    • Exporting Data Off of Netezza into an External Table
    • Importing Data into Netezza Using an External Table
    • What is the Problem Here?
  • Sub-query Functions
    • An IN List is much like a Subquery
    • An IN List Never has Duplicates - Just like a Subquery
    • An IN List Ignores Duplicates
    • The Subquery
    • How a Basic Subquery Works
    • The Final Answer Set from the Subquery
    • The Basics of a Correlated Subquery
    • The Top Query always runs first in a Correlated Subquery
    • The Bottom Query runs last in a Correlated Subquery
    • Correlated Subquery Example vs. a Join with a Derived Table
    • Correlated Subquery that Finds Duplicates
    • How the Double Parameter Subquery Works
    • More on how the Double Parameter Subquery Works
    • How to handle a NOT IN with Potential NULL Values
    • IN is equivalent to =ANY
    • Using a Correlated Exists
    • How a Correlated Exists matches up
    • The Correlated NOT Exists
    • The Correlated NOT Exists Answer Set
  • Substrings and Positioning Functions
    • The LOWER Function
    • The UPPER Function
    • CHARACTER_LENGTH
    • OCTET_LENGTH
    • TRIM for Troubleshooting the CHARACTERS Command
    • The TRIM Command trims both Leading and Trailing Spaces
    • Trim and Trailing is Case Sensitive
    • Trim and Trailing works if Case right
    • Trim Combined with the CHARACTERS Command
    • How to TRIM only the Trailing Spaces
    • How to TRIM Trailing Letters
    • How to TRIM Trailing Letters and use CHARACTER_Length
    • LTRIM Function
    • RTRIM Function
    • BTRIM Function
    • The SUBSTRING Command
    • How SUBSTRING Works with NO ENDING POSITION
    • Using SUBSTRING to move backwards
    • How SUBSTRING Works with a Starting Position of -1
    • How SUBSTRING Works with an Ending Position of 0
    • An Example using SUBSTRING, TRIM, and CHAR Together
    • SUBSTRING and SUBSTR are equal, but use different syntax
    • The POSITION Command finds a Letters Position
    • STRPOS Function
    • The POSITION and STRPOS Do the Same Thing
    • SUBSTRING and POSITION Used Together In an UPDATE
    • The POSITION Command is brilliant with SUBSTRING
    • Using the SUBSTRING to Find the Second Word On
    • Concatenation
    • Concatenation and SUBSTRING
    • Four Concatenations Together
    • Troubleshooting Concatenation
    • Miscellaneous Character Functions - ASCII
    • Miscellaneous Character Functions - CHR
    • Miscellaneous Character Functions - INITCAP
    • Miscellaneous Character Functions - REPEAT
    • Miscellaneous Character Functions - TRANSLATE
    • Character Padding Functions - LPAD Function
    • Character Padding Functions - RPAD Function
  • Interrogating the Data
    • NVL Syntax
    • NVL Example
    • NVL Is Often Used With Calculations
    • Comparisons of NVL
    • A Real-World NVL Example
    • NVL2 Syntax
    • NVL2 Example
    • NVL2 Syntax
    • A Real-World NVL2 Example
    • DECODE Syntax
    • DECODE Example
    • A Real-World DECODE Example
    • The COALESCE Command
    • The COALESCE Answer Set
    • The Basics of CAST (Convert and Store)
    • Some Great CAST (Convert and Store) Examples
    • Round Function
    • Round Function Continued
    • The Basics of the CASE Statements
    • The Basics of the CASE Statement shown visually
    • Valued Case Vs. A Searched Case
    • When an ELSE is present in CASE Statement
    • When NO ELSE is present in CASE Statement
    • When an Alias is NOT used in a CASE Statement
    • When an Alias is NOT used in a CASE Statement
    • Combining Searched Case and Valued Case
    • A Trick for getting a Horizontal Case
    • Nested Case
    • Put a CASE in the ORDER BY
  • View Functions
    • Creating a Simple View
    • Basic Rules for Views
    • Views sometimes CREATED for Formatting or Row Security
    • Another Way to Alias Columns in a View CREATE
    • Resolving Aliasing Problems in a View CREATE
    • Resolving Aliasing Problems in a View CREATE
    • Resolving Aliasing Problems in a View CREATE
    • CREATING Views for Complex SQL such as Joins
    • WHY certain columns need Aliasing in a View
    • Using a WHERE Clause When Selecting From a View
    • Altering a Table
    • Altering a Table after a View has been created
    • A View that Errors after an ALTER
    • Troubleshooting a View
  • Set Operators Functions
    • Rules of Set Operators
    • INTERSECT Explained Logically
    • INTERSECT Explained Logically
    • UNION Explained Logically
    • UNION Explained Logically
    • UNION ALL Explained Logically
    • UNION Explained Logically
    • EXCEPT Explained Logically
    • EXCEPT Explained Logically
    • Minus Explained Logically
    • Minus Explained Logically
    • Testing Your Knowledge
    • Testing Your Knowledge
    • An Equal Amount of Columns in both SELECT List
    • Columns in the SELECT list should be from the same Domain
    • The Top Query handles all Aliases
    • The Bottom Query does the ORDER BY (a Number)
    • Great Trick:Place your Set Operator in a Derived Table
    • UNION Vs UNION ALL
    • Using UNION ALL and Literals
    • A Great Example of how EXCEPT works
    • USING Multiple SET Operators in a Single Request
    • Changing the Order of Precedence with Parentheses
    • Using UNION to be same as GROUP BY GROUPING SETS
    • Using UNION to be same as GROUP BY ROLLUP
    • Using UNION to be the same as GROUP BY Cube
    • Using UNION to be same as GROUP BY Cube
  • Data Manipulations
    • Netezza Transactions
    • BEGIN Command
    • COMMIT Command
    • What Happens on a Transaction Error?
    • Can I See My Uncommitted Changes?
    • Until the Commit Others Can't See Your Changes?
    • ROLLBACK Command
    • ROLLBACK Command in ACTION
    • INSERT Command
    • INSERT With Keyword Null
    • A Different Syntax for the INSERT Statements
    • These Three Statements are the same
    • A Third Way of Doing an INSERT
    • Netezza Has Implemented the Default Values Clause
    • INSERT/SELECT
    • INSERT/SELECT Examples
    • Another Syntax for the INSERT/SELECT
    • INSERT/SELECT Used To CREATE A Data Mart
    • UPDATE
    • An UPDATE in Action
    • An UPDATE with Multiple WHERE and AND Clauses
    • An UPDATE with Multiple WHERE and AND Clauses
    • UPDATE Using a Subquery
    • UPDATE Using A Join
    • DELETE
    • Two DELETE Examples
    • DELETE Through a Subquery or Join
    • DELETE Through a Subquery and A Join Examples
    • Multi-Statement Example
    • How to Undo a Delete
    • A Delete Example Query
    • How to Undo a Delete
    • How to Undo a Delete in Action
  • Tables, DDL, and Data Types
    • CREATE TABLE Syntax
    • Viewing the DDL
    • Netezza Tables - Distribution Key or Random Distribution
    • Table CREATE Examples with 4 different Distribution Keys
    • The Worst Mistake You Can Make For a Distribution Key
    • Good things to know about Table and Object Names
    • Netezza Data Types
    • Netezza Data Types in More Detail
    • Netezza Data Type Extensions
    • Reserved Names within a Table
    • How to Query and See Non-Active Rows
    • Column Attributes
    • Constraints
    • Column Level Constraint Example
    • Defining Constraints at the Table Level
    • Utilizing Default Values for a Table
    • CTAS (Create Table AS)
    • CTAS Facts
    • Using the CTAS (Create Table AS) Table for Co-Location
    • Altering a CTAS Table to Rename It
    • FPGA Card and Zone Maps - The Netezza Secret Weapon
    • How A CTAS with ORDER BY Improves Queries
    • A CTAS Major Sort Benefits over the Minor Sort
    • Altering a Table
    • Altering a Table Examples
    • Drop Table, Truncate, and Delete Compared
    • Creating and Dropping a Netezza Database
    • How to Determine the Database you are in?
    • Netezza Users
    • Altering a Netezza User
    • Reserved Words to find out about a User
  • Statistical Aggregate Functions
    • The Stats Table
    • The STDDEV_POP Function
    • A STDDEV_POP Example
    • The STDDEV_SAMP Function
    • A STDDEV_SAMP Example
    • The VAR_POP Function
    • A VAR_POP Example
    • The VAR_SAMP Function
    • A VAR_SAMP Example
    • Using GROUP BY
    • A Great Query Example
  • Stored Procedure Functions
    • Netezza Stored Procedures
    • Creating and Executing a Stored Procedure
    • Creating a Stored Procedure
    • Netezza Provides Multiple Ways to Run the Stored Procedure
    • You Can Have Multiple BEGIN and END statements
    • How to Declare and Set a Variable
    • Declaring a Variable with a Value
    • Input Parameters
    • Input Parameters Using Character Data
    • Calling a Procedure with Multiple Input Parameters
    • CREATE OR REPLACE Procedure
    • IF THEN ELSE IF Techniques
    • An Easier Way for IF THEN ELSE is ELSIF or ELSEIF
    • Using Loops in Stored Procedures
    • Using Loops with Different EXIT strategies
    • Looping With the WHILE Statement
    • Stored Procedure Workshop
    • Stored Procedure Workshop
    • Using a FOR Loop
  • Nexus Query Chameleon
    • The Old Nexus Logo
    • The New Nexus Logo
    • Watch the Video on the new Nexus Super Join Builder
    • How to Customize your System Tree View
    • Introducing the new Nexus Super Join Builder
    • Define your Joins and tell Nexus to Add and Remember Me"
    • Nexus knows what Tables Join together
    • Nexus Presents Tables and their columns in Color
    • Nexus Builds your SQL Automagically
    • Nexus can Cube a Table and Join to Everything Possible
    • Nexus can Cube a Table and Join to Everything Possible
    • The Cube SQL created Automagically
    • Manipulate the Columns with the Columns Tab
    • Single Click and ORDER BY using the Sort Tab
    • Using the Joins Tab of Nexus
    • The SQL Tab reflects the changes we make in all other Tabs
    • WHERE Tab shows Tables Indexes
    • The Answer Set Tab shows the Results
    • The Metadata Tab shows Metadata
    • Nexus Makes a View look like a Table
    • Nexus Joins Views to other Views in seconds
    • Nexus can Cube a View and Join to all other related Views
    • Nexus Cubes Views in Seconds
    • The Cube SQL created on Views is done Automagically
    • Views with the Underlying Indexes of the Base Tables
    • WHERE Tab shows Views Underlying Base Table Indexes
    • After an Answer Set Returns, you can do many things
    • After an Answer Set Returns, Perform OLAP Calculations
    • After an Answer Set Returns, you can Graph and Chart
    • Custom Joins With Nexus
    • Users Who Want to Load the Model
    • Users Who Want to Load the Model (Continued)
    • How Custom Joins Will Look in the Super Join Builder
    • Loading an ERwin Mode
    • Loading an ERwin Model (Continued)
    • Attaching the ERwin Model
    • Attaching the ERwin Model (Continued)
    • Managing the ERwin Model (Continued)
    • Saving an Answer Set in another Format
    • Sandbox - How to Create a Sandbox (1 of 5)
    • Convert Netezza DDL to another Database Vendor
    • Replicate Data from One Netezza System to Another

Schedule

No public classes currenly scheduled. Please contact us about the possibility of a scheduling a private class.

No public classes currenly scheduled. Please contact us about the possibility of a scheduling a private class.

Learn faster

Our live, instructor-led lectures are far more effective than pre-recorded classes

Satisfaction guarantee

If your team is not 100% satisfied with your training, we do what's necessary to make it right

Learn online from anywhere

Whether you are at home or in the office, we make learning interactive and engaging

Multiple Payment Options

We accept check, ACH/EFT, major credit cards, and most purchase orders



Recent Training Locations

Alabama

Birmingham

Huntsville

Montgomery

Alaska

Anchorage

Arizona

Phoenix

Tucson

Arkansas

Fayetteville

Little Rock

California

Los Angeles

Oakland

Orange County

Sacramento

San Diego

San Francisco

San Jose

Colorado

Boulder

Colorado Springs

Denver

Connecticut

Hartford

DC

Washington

Florida

Fort Lauderdale

Jacksonville

Miami

Orlando

Tampa

Georgia

Atlanta

Augusta

Savannah

Hawaii

Honolulu

Idaho

Boise

Illinois

Chicago

Indiana

Indianapolis

Iowa

Cedar Rapids

Des Moines

Kansas

Wichita

Kentucky

Lexington

Louisville

Louisiana

New Orleans

Maine

Portland

Maryland

Annapolis

Baltimore

Frederick

Hagerstown

Massachusetts

Boston

Cambridge

Springfield

Michigan

Ann Arbor

Detroit

Grand Rapids

Minnesota

Minneapolis

Saint Paul

Mississippi

Jackson

Missouri

Kansas City

St. Louis

Nebraska

Lincoln

Omaha

Nevada

Las Vegas

Reno

New Jersey

Princeton

New Mexico

Albuquerque

New York

Albany

Buffalo

New York City

White Plains

North Carolina

Charlotte

Durham

Raleigh

Ohio

Akron

Canton

Cincinnati

Cleveland

Columbus

Dayton

Oklahoma

Oklahoma City

Tulsa

Oregon

Portland

Pennsylvania

Philadelphia

Pittsburgh

Rhode Island

Providence

South Carolina

Charleston

Columbia

Greenville

Tennessee

Knoxville

Memphis

Nashville

Texas

Austin

Dallas

El Paso

Houston

San Antonio

Utah

Salt Lake City

Virginia

Alexandria

Arlington

Norfolk

Richmond

Washington

Seattle

Tacoma

West Virginia

Charleston

Wisconsin

Madison

Milwaukee

Alberta

Calgary

Edmonton

British Columbia

Vancouver

Manitoba

Winnipeg

Nova Scotia

Halifax

Ontario

Ottawa

Toronto

Quebec

Montreal

Puerto Rico

San Juan