Amazon Redshift SQL translation guide
This document details the similarities and differences in SQL syntax betweenAmazon Redshift and BigQuery to help you plan your migration. Usebatch SQL translation tomigrate your SQL scripts in bulk, orinteractive SQL translationto translate ad hoc queries.
The intended audience for this guide is enterprise architects, databaseadministrators, application developers, and IT security specialists. Itassumes you are familiar with Amazon Redshift.
Note: In some cases, there is no direct mapping between a SQL element inAmazon Redshift and BigQuery. However, in most cases, youcan achieve the same functionality in BigQuery that you can inAmazon Redshift using alternative means, as shown in the examplesin this document.Data types
This section shows equivalents between data types in Amazon Redshift and in BigQuery.
| Amazon Redshift | BigQuery | Notes | |
|---|---|---|---|
| Data type | Alias | Data type | |
SMALLINT | INT2 | INT64 | Amazon Redshift'sSMALLINT is 2 bytes, whereas BigQuery'sINT64 is 8 bytes. |
INTEGER | INT64 | Amazon Redshift'sINTEGER is 4 bytes, whereas BigQuery'sINT64 is 8 bytes. | |
BIGINT | INT8 | INT64 | Both Amazon Redshift'sBIGINT and BigQuery'sINT64 are 8 bytes. |
DECIMAL | NUMERIC | NUMERIC | |
REAL | FLOAT4 | FLOAT64 | Amazon Redshift'sREAL is 4 bytes, whereas BigQuery'sFLOAT64 is 8 bytes. |
DOUBLEPRECISION | FLOAT64 | ||
BOOLEAN | BOOL | BOOL | Amazon Redshift'sBOOLEAN can useTRUE,t,true,y,yes, and1 as valid literal values for true. BigQuery'sBOOL data type uses case-insensitiveTRUE. |
CHAR | STRING | ||
VARCHAR | STRING | ||
DATE | DATE | ||
TIMESTAMP | TIMESTAMP WITHOUT TIME ZONE | DATETIME | |
TIMESTAMPTZ | TIMESTAMP | Note: In BigQuery,time zones are used when parsingtimestamps or formatting timestamps for display. A string-formattedtimestamp might include a time zone, but when BigQuery parses thestring, it stores the timestamp in the equivalent UTC time. When atime zone is not explicitly specified, the default time zone, UTC, isused.Time zonenames oroffset from UTC using (-|+)HH:MMare supported, but time zone abbreviations such as PDT are notsupported. | |
GEOMETRY | GEOGRAPHY | Support for querying geospatial data. | |
BigQuery also has the following data types that do not have a direct Amazon Redshiftanalog:
Implicit conversion types
When migrating to BigQuery, you need to convert most of yourAmazon Redshift implicit conversionsto BigQuery's explicit conversions except for the following data types, whichBigQuery implicitly converts.
BigQuery performs implicit conversions for the following data types:
| From BigQuery type | To BigQuery type |
|---|---|
|
|
|
|
|
|
BigQuery also performs implicit conversions for the following literals:
| From BigQuery type | To BigQuery type |
|---|---|
STRING literal(e.g. "2008-12-25") |
|
STRING literal(e.g. "2008-12-25 15:30:00") |
|
STRING literal(e.g. "2008-12-25T07:30:00") |
|
STRING literal(e.g. "15:30:00") |
|
Explicit conversion types
You can convert Amazon Redshift data types that BigQuery doesn't implicitly convertusing BigQuery'sCAST(expression AS type) functionor any of theDATEandTIMESTAMPconversion functions.
When migrating your queries, change any occurrences of the Amazon RedshiftCONVERT(type, expression)function (or the :: syntax) to BigQuery'sCAST(expression AS type) function,as shown in the table in theData type formatting functions section.
Query syntax
This section addresses differences in query syntax between Amazon Redshift andBigQuery.
SELECT statement
Most Amazon RedshiftSELECTstatements are compatible with BigQuery. The following table contains a list ofminor differences.
| Amazon Redshift | BigQuery |
|---|---|
|
|
|
|
BigQuery also supports the following expressions inSELECT statements, which donot have a Amazon Redshift equivalent:
FROM clause
AFROMclause in a query lists the table references that data is selected from. InAmazon Redshift, possible table references include tables, views, and subqueries. Allof these table references are supported in BigQuery.
BigQuery tables can be referenced in theFROMclause using the following:
[project_id].[dataset_id].[table_name][dataset_id].[table_name][table_name]
BigQuery also supports additional table references:
- Historical versions of the table definition and rows using
FOR SYSTEM_TIME AS OF. - Field paths,or any path that resolves to a field within a data type (such as a
STRUCT). - Flattened arrays.
JOIN types
Both Amazon Redshift and BigQuery support the following types of join:
[INNER] JOINLEFT [OUTER] JOINRIGHT [OUTER] JOINFULL [OUTER] JOINCROSS JOINand the equivalentimplicit comma cross join.
The following table contains a list of minor differences.
| Amazon Redshift | BigQuery |
|---|---|
|
Note: In BigQuery, JOIN clauses require aJOIN condition unless the clause is aCROSSJOIN or one of the joined tables is a field within a data typeor an array. |
WITH clause
A BigQueryWITHclause contains one or more named subqueries that execute when a subsequentSELECT statement references them. Amazon RedshiftWITHclauses behave the same as BigQuery's with the exception that you can evaluatethe clause once and reuse its results.
Set operators
There are some minor differences betweenAmazon Redshift set operatorsandBigQuery setoperators.However, all set operations that are feasible in Amazon Redshift are replicable inBigQuery.
| Amazon Redshift | BigQuery |
|---|---|
|
Note: Both BigQuery and Amazon Redshift support the |
|
|
|
|
|
|
|
Note: BigQuery requires parentheses to separate different setoperations. If the same set operator is repeated, parentheses are notnecessary. |
ORDER BY clause
There are some minor differences between Amazon RedshiftORDER BYclauses and BigQueryORDER BYclauses.
| Amazon Redshift | BigQuery |
|---|---|
In Amazon Redshift,NULLs are ranked last by default (ascendingorder). | In BigQuery,NULLs are ranked first by default(ascending order). |
|
Note: BigQuery does not use the LIMIT ALL syntax, butORDER BY sorts all rows by default, resulting in thesame behavior as Amazon Redshift'sLIMIT ALL clause. We highlyrecommend including aLIMIT clause with everyORDER BY clause. Ordering all result rows unnecessarilydegrades query execution performance. |
|
Note: In BigQuery, OFFSET must be used together with aLIMITcount. Make sure to set thecountINT64 value to the minimum necessary ordered rows.Ordering all result rowsunnecessarily degrades query execution performance. |
Conditions
The following tableshowsAmazon Redshift conditions,or predicates, that are specific to Amazon Redshift and must be converted to theirBigQuery equivalent.
| Amazon Redshift | BigQuery |
|---|---|
|
|
|
|
| |
|
Note: BigQuery does not support custom escape characters. You mustuse two backslashes \\ as escape characters for BigQuery. |
|
Note: If NOT is specified, wrap the aboveIF expression in aNOT expression as shownbelow:
|
|
|
Functions
The following sections list Amazon Redshift functions and their BigQuery equivalents.
Aggregate functions
The following table shows mappings between common Amazon Redshift aggregate, aggregateanalytic, and approximate aggregate functions with their BigQuery equivalents.
| Amazon Redshift | BigQuery |
|---|---|
APPROXIMATECOUNT(DISTINCT expression) | APPROX_COUNT_DISTINCT(expression) |
APPROXIMATEPERCENTILE_DISC( | APPROX_QUANTILES(expression,100) |
AVG([DISTINCT] expression) | AVG([DISTINCT] expression) |
COUNT(expression) | COUNT(expression) |
LISTAGG( | STRING_AGG( |
MAX(expression) | MAX(expression) |
MEDIAN(median_expression) | PERCENTILE_CONT( median_expression, 0.5) OVER() |
MIN(expression) | MIN(expression) |
PERCENTILE_CONT( | PERCENTILE_CONT(Note: Does not cover aggregation use cases. |
STDDEV([DISTINCT] expression) | STDDEV([DISTINCT] expression) |
STDDEV_SAMP([DISTINCT] expression) | STDDEV_SAMP([DISTINCT] expression) |
STDDEV_POP([DISTINCT] expression) | STDDEV_POP([DISTINCT] expression) |
SUM([DISTINCT] expression) | SUM([DISTINCT] expression) |
VARIANCE([DISTINCT] expression) | VARIANCE([DISTINCT] expression) |
VAR_SAMP([DISTINCT] expression) | VAR_SAMP([DISTINCT] expression) |
VAR_POP([DISTINCT] expression) | VAR_POP([DISTINCT] expression) |
BigQuery also offers the followingaggregate,aggregate analytic,andapproximate aggregatefunctions, which do not have a direct analogue in Amazon Redshift:
Bitwise aggregate functions
The following table shows mappings between common Amazon Redshift bitwise aggregatefunctions with their BigQuery equivalents.
| Amazon Redshift | BigQuery |
|---|---|
BIT_AND(expression) | BIT_AND(expression) |
BIT_OR(expression) | BIT_OR(expression) |
BOOL_AND>(expression) | LOGICAL_AND(expression) |
BOOL_OR(expression) | LOGICAL_OR(expression) |
BigQuery also offers the followingbit-wise aggregatefunction, which does not have a direct analogue in Amazon Redshift:
Window functions
The following table shows mappings between common Amazon Redshift window functionswith their BigQuery equivalents. Windowing functions in BigQuery includeanalytic aggregate functions,aggregate functions,navigation functions,andnumbering functions.
| Amazon Redshift | BigQuery |
|---|---|
AVG(expression) OVER | AVG(expression) OVER |
COUNT(expression) OVER | COUNT(expression) OVER |
CUME_DIST() OVER | CUME_DIST() OVER |
DENSE_RANK() OVER | DENSE_RANK() OVER |
FIRST_VALUE(expression)OVER | FIRST_VALUE(expression)OVER |
LAST_VALUE(expression) OVER | LAST_VALUE(expression) OVER |
LAG(value_expr [, offset])OVER | LAG(value_expr [, offset])OVER |
LEAD(value_expr [, offset])OVER | LEAD(value_expr [, offset])OVER |
LISTAGG( | STRING_AGG( |
MAX(expression) OVER | MAX(expression) OVER |
MEDIAN(median_expression)OVER | PERCENTILE_CONT( |
MIN(expression) OVER | MIN(expression) OVER |
NTH_VALUE(expression,offset) OVER ([PARTITION BY window_partition] [ORDER BY window_orderingframe_clause]) | NTH_VALUE(expression,offset) OVER |
NTILE(expr) OVER | NTILE(expr) OVER |
PERCENT_RANK() OVER | PERCENT_RANK() OVER |
PERCENTILE_CONT(percentile) | PERCENTILE_CONT(expr,percentile) OVER |
PERCENTILE_DISC(percentile)WITHIN GROUP (ORDER BY expr) OVER | PERCENTILE_DISC(expr,percentile) OVER |
RANK() OVER | RANK() OVER |
RATIO_TO_REPORT(ratio_expression)OVER | ratio_expressionSUM(ratio_expression) OVER |
ROW_NUMBER() OVER | ROW_NUMBER() OVER |
STDDEV(expression) OVER | STDDEV(expression) OVER |
STDDEV_SAMP(expression)OVER | STDDEV_SAMP(expression)OVER |
STDDEV_POP(expression) OVER | STDDEV_POP(expression) OVER |
SUM(expression) OVER | SUM(expression) OVER |
VAR_POP(expression) OVER | VAR_POP(expression) OVER |
VAR_SAMP(expression) OVER | VAR_SAMP(expression) OVER |
VARIANCE(expression) OVER | VARIANCE(expression) OVER |
Conditional expressions
The following table shows mappings between common Amazon Redshift conditionalexpressions with their BigQuery equivalents.
| Amazon Redshift | BigQuery |
|---|---|
CASEexpression | CASE expression |
COALESCE(expression1[,...]) | COALESCE(expression1[,...]) |
DECODE( | CASE expression |
GREATEST(value [,...]) | GREATEST(value [,...]) |
LEAST(value [, ...]) | LEAST(value [, ...]) |
NVL(expression1[, ...]) | COALESCE(expression1[,...]) |
NVL2( | IF( |
NULLIF(expression1,expression2) | NULLIF(expression1,expression2) |
BigQuery also offers the following conditional expressions, which do not have adirect analogue in Amazon Redshift:
Date and time functions
The following table shows mappings between common Amazon Redshift date and timefunctions with their BigQuery equivalents. BigQuery data and time functionsincludedate functions,datetimefunctions,time functions,andtimestamp functions.
Keep in mind that functions that seem identical in Amazon Redshift and BigQuery mightreturn different data types.
| Amazon Redshift | BigQuery |
|---|---|
ADD_MONTHS( | CAST(DATE_ADD( |
timestamptz_or_timestampAT TIMEZONE timezone | PARSE_TIMESTAMP(Note:Time zones are used when parsingtimestamps or formatting timestamps for display. A string-formattedtimestamp might include a time zone, but when BigQuery parses thestring, it stores the timestamp in the equivalent UTC time. When atime zone is not explicitly specified, the default time zone, UTC, isused.Time zone names oroffset from UTC (-HH:MM) aresupported, but time zone abbreviations (such as PDT) are notsupported. |
CONVERT_TIMEZONE( | PARSE_TIMESTAMP(Note: source_timezone is UTC in BigQuery. |
CURRENT_DATENote: Returns start date for the current transaction in the currentsession time zone (UTC by default). | CURRENT_DATE()Note: Returns start date for the current statement in the UTC timezone. |
DATE_CMP(date1, date2) | CASE |
DATE_CMP_TIMESTAMP(date1,date2) | CASE |
DATE_CMP_TIMESTAMPTZ(date,timestamptz) | CASE |
DATE_PART_YEAR(date) | EXTRACT(YEAR FROMdate) |
DATEADD(date_part,interval, date) | CAST( |
DATEDIFF( | DATE_DIFF( |
DATE_PART(date_part, date) | EXTRACT(date_part FROMdate) |
DATE_TRUNC('date_part',timestamp) | TIMESTAMP_TRUNC(timestamp,date_part) |
EXTRACT(date_part FROMtimestamp) | EXTRACT(date_part FROMtimestamp) |
GETDATE() | PARSE_TIMESTAMP( |
INTERVAL_CMP( | For intervals in Redshift, there are 360 days in a year. In BigQuery, you can use the following user-defined function (UDF) to parse a Redshift interval andtranslate it to seconds.CREATE TEMP FUNCTIONTo compare interval literals, perform: IF( |
LAST_DAY(date) | DATE_SUB( |
MONTHS_BETWEEN( | DATE_DIFF( |
NEXT_DAY(date, day) | DATE_ADD( |
SYSDATENote: Returns start timestamp for the current transaction in thecurrent session time zone (UTC by default). | CURRENT_TIMESTAMP()Note: Returns start timestamp for the current statement in the UTC timezone. |
TIMEOFDAY() | FORMAT_TIMESTAMP( |
TIMESTAMP_CMP( | CASE |
TIMESTAMP_CMP_DATE( | CASE |
TIMESTAMP_CMP_TIMESTAMPTZ(Note: Redshift compares timestamps in the user session-defined timezone. Default user session time zone is UTC. | CASENote: BigQuery compares timestamps in the UTC time zone. |
TIMESTAMPTZ_CMP(Note: Redshift compares timestamps in the user session-defined timezone. Default user session time zone is UTC. | CASENote: BigQuery compares timestamps in the UTC time zone. |
TIMESTAMPTZ_CMP_DATE(Note: Redshift compares timestamps in the user session-defined timezone. Default user session time zone is UTC. | CASENote: BigQuery compares timestamps in the UTC time zone. |
TIMESTAMPTZ_CMP_TIMESTAMP(Note: Redshift compares timestamps in the user session-defined timezone. Default user session time zone is UTC. | CASENote: BigQuery compares timestamps in the UTC time zone. |
TIMEZONE( | PARSE_TIMESTAMP(Note:Time zones are used when parsingtimestamps or formatting timestamps for display. A string-formattedtimestamp might include a time zone, but when BigQuery parses thestring, it stores the timestamp in the equivalent UTC time. When atime zone is not explicitly specified, the default time zone, UTC, isused.Time zone names oroffset from UTC (-HH:MM) aresupported but time zone abbreviations (such as PDT) are notsupported. |
TO_TIMESTAMP(timestamp,format) | PARSE_TIMESTAMP(Note: BigQuery follows a different set offormat elements.Time zones are used when parsingtimestamps or formatting timestamps for display. A string-formattedtimestamp might include a time zone, but when BigQuery parses thestring, it stores the timestamp in the equivalent UTC time. When atime zone is not explicitly specified, the default time zone, UTC, isused.Time zone names oroffset from UTC (-HH:MM) aresupported in the format string but time zone abbreviations (such asPDT) are not supported. |
TRUNC(timestamp) | CAST(timestamp ASDATE) |
BigQuery also offers the following date and time functions, which do not have adirect analogue in Amazon Redshift:
EXTRACTDATEDATE_SUBDATE_ADD(returningDATEdata type)DATE_FROM_UNIX_DATEFORMAT_DATEPARSE_DATEUNIX_DATEDATETIMEDATETIME_ADDDATETIME_SUBDATETIME_DIFFDATETIME_TRUNCFORMAT_DATETIMEPARSE_DATETIMECURRENT_TIMETIMETIME_ADDTIME_SUBTIME_DIFFTIME_TRUNCFORMAT_TIMEPARSE_TIMETIMESTAMP_SECONDSTIMESTAMP_MILLISTIMESTAMP_MICROSUNIX_SECONDSUNIX_MILLISUNIX_MICROS
Mathematical operators
The following table shows mappings between common Amazon Redshift mathematicaloperators with their BigQuery equivalents.
| Amazon Redshift | BigQuery |
|---|---|
|
|
|
|
|
|
Note: If the operator is performing integer division (in other words, if X andY are bothintegers), an integer is returned. If the operator is performingnon-integer division, a non-integer is returned. | If integer division:CAST(FLOOR(X / Y) AS INT64)If not integer division:
Note: Division in BigQuery returns a non-integer. To prevent errors from a division operation (division by zero error),use SAFE_DIVIDE(X, Y)orIEEE_DIVIDE(X, Y). |
|
Note: To prevent errors from a division operation (division by zeroerror), use SAFE.MOD(X, Y).SAFE.MOD(X, 0) results in 0. |
|
Note: Unlike Amazon Redshift, the ^ operator inBigQuery performs Bitwisexor. |
|
Note: To prevent errors from a square root operation (negativeinput), use SAFE.SQRT(X). Negative inputwithSAFE.SQRT(X) results inNULL. |
| Note: BigQuery's POWER(X, Y) returns anerror ifX is a finite value less than 0 andY is a noninteger. |
|
|
|
Note: This operator returns 0 or a byte sequence of b'\x00' if thesecond operand Y is greater than or equal to the bit length of thefirst operandX (for example, 64 ifX has the type INT64). Thisoperator throws an error ifY is negative. |
|
Note: Shifts the first operand X to the right. This operator does notdo sign bit extension with a signed type (it fills vacant bits on theleft with 0). This operator returns 0 or a byte sequence ofb'\x00' if the second operand Y is greater than or equal to the bitlength of the first operandX (for example, 64 ifX has the typeINT64). This operator throws an error ifY is negative. |
|
|
|
|
|
|
BigQuery also offers the following mathematical operator, which does not have adirect analog in Amazon Redshift:
X ^ Y(Bitwisexor)
Math functions
| Amazon Redshift | BigQuery |
|---|---|
ABS(number) | ABS(number) |
ACOS(number) | ACOS(number) |
ASIN(number) | ASIN(number) |
ATAN(number) | ATAN(number) |
ATAN2(number1,number2) | ATAN2(number1,number2) |
CBRT(number) | POWER(number, 1/3) |
CEIL(number) | CEIL(number) |
CEILING(number) | CEILING(number) |
CHECKSUM(expression) | FARM_FINGERPRINT(expression) |
COS(number) | COS(number) |
COT(number) | 1/TAN(number) |
DEGREES(number) | number*180/ACOS(-1) |
DEXP(number) | EXP(number) |
DLOG1(number) | LN(number) |
DLOG10(number) | LOG10(number) |
EXP(number) | EXP(number) |
FLOOR(number) | FLOOR(number) |
LNnumber) | LN(number) |
LOG(number) | LOG10(number) |
MOD(number1, number2) | MOD(number1, number2) |
PI | ACOS(-1) |
POWER(expression1,expression2) | POWER(expression1, expression2) |
RADIANS(number) | ACOS(-1)*(number/180) |
RANDOM() | RAND() |
ROUND(number [,integer]) | ROUND(number [,integer]) |
SIN(number) | SIN(number) |
SIGN(number) | SIGN(number) |
SQRT(number) | SQRT(number) |
TAN(number) | TAN(number) |
TO_HEX(number) | FORMAT('%x', number) |
TRUNC(number [,integer])+-+++ | TRUNC(number [, integer]) |
String functions
| Amazon Redshift | BigQuery |
|---|---|
string1|| string2 | CONCAT(string1,string2) |
BPCHARCMP(string1,string2) | CASE |
BTRIM(string [,matching_string]) | TRIM(string [,matching_string]) |
BTTEXT_PATTERN_CMP(string1,string2) | CASE |
CHAR_LENGTH(expression) | CHAR_LENGTH(expression) |
CHARACTER_LENGTH(expression) | CHARACTER_LENGTH(expression) |
CHARINDEX(substring,string) | STRPOS(string, substring) |
CHR(number) | CODE_POINTS_TO_STRING([number]) |
CONCAT(string1,string2) | CONCAT(string1, string2)Note: BigQuery's CONCAT(...) supportsconcatenating any number of strings. |
CRC32 | Custom user-defined function |
FUNC_SHA1(string) | SHA1(string) |
INITCAP | INITCAP |
LEFT(string, integer) | SUBSTR(string, 0, integer) |
RIGHT(string, integer) | SUBSTR(string,-integer) |
LEN(expression) | LENGTH(expression) |
LENGTH(expression) | LENGTH(expression) |
LOWER(string) | LOWER(string) |
LPAD(string1, length[,string2]) | LPAD(string1, length[,string2]) |
RPAD(string1, length[,string2]) | RPAD(string1, length[,string2]) |
LTRIM(string,trim_chars) | LTRIM(string,trim_chars) |
MD5(string) | MD5(string) |
OCTET_LENGTH(expression) | BYTE_LENGTH(expression) |
POSITION(substring INstring) | STRPOS(string,substring) |
QUOTE_IDENT(string) | CONCAT('"',string,'"') |
QUOTE_LITERAL(string) | CONCAT("'",string,"'") |
REGEXP_COUNT(source_string, pattern | ARRAY_LENGTH(REGEXP_EXTRACT_ALL(If position is specified:ARRAY_LENGTH(REGEXP_EXTRACT_ALL(Note: BigQuery provides regular expression support using the re2 library; see thatdocumentation for its regular expression syntax. |
REGEXP_INSTR( | IFNULL(STRPOS(If source_string is specified:REGEXP_REPLACE(If position is specified:IFNULL(STRPOS(If occurrence is specified:IFNULL(STRPOS(Note: BigQuery provides regular expression support using the re2library; see thatdocumentation for its regular expression syntax. |
REGEXP_REPLACE(source_string, | REGEXP_REPLACE(If source_string is specified:REGEXP_REPLACE(If position is specified:CASE |
REGEXP_SUBSTR(source_string, pattern | REGEXP_EXTRACT(If position is specified:REGEXP_EXTRACT(If occurrence is specified:REGEXP_EXTRACT_ALL(Note: BigQuery provides regular expression support using the re2 library; see thatdocumentation for its regular expression syntax. |
REPEAT(string,integer) | REPEAT(string,integer) |
REPLACE(string, old_chars,new_chars) | REPLACE(string, old_chars,new_chars) |
REPLICA(string,integer) | REPEAT(string,integer) |
REVERSE(expression) | REVERSE(expression) |
RTRIM(string,trim_chars) | RTRIM(string,trim_chars) |
SPLIT_PART(string,delimiter, part) | SPLIT( |
STRPOS(string,substring) | STRPOS(string,substring) |
STRTOL(string, base) | |
SUBSTRING( | SUBSTR( |
TEXTLEN(expression) | LENGTH(expression) |
TRANSLATE( | Can be implemented using UDFs:CREATE TEMP FUNCTION |
TRIM([BOTH] string) | TRIM(string) |
TRIM([BOTH] characters FROMstring) | TRIM(string, characters) |
UPPER(string) | UPPER(string) |
Data type formatting functions
| Amazon Redshift | BigQuery |
|---|---|
CAST(expression AS type) | CAST(expression AS type) |
expression::type | CAST(expression AS type) |
CONVERT(type, expression) | CAST(expression AS type) |
TO_CHAR( | FORMAT_TIMESTAMP(Note: BigQuery and Amazon Redshift differ in how to specify a format string for timestamp_expression. |
TO_CHAR( | FORMAT(Note: BigQuery and Amazon Redshiftdiffer in how to specify a format string for timestamp_expression. |
TO_DATE(date_string, format) | PARSE_DATE(date_string, format)Note: BigQuery and Amazon Redshift differ in how to specify a format string for date_string. |
TO_NUMBER(string, format) | CAST(Note: BigQuery and Amazon Redshift differ in how to specify a numeric format string. |
BigQuery also supportsSAFE_CAST(expressionAS typename), which returnsNULL if BigQuery is unable to perform a cast; forexample,SAFE_CAST("apple"AS INT64) returnsNULL.
DML syntax
This section addresses differences in data management language syntax betweenAmazon Redshift and BigQuery.
INSERT statement
Amazon Redshift offers a configurableDEFAULT keyword for columns. InBigQuery, theDEFAULT value for nullable columns isNULL,andDEFAULT is not supported forrequired columns. MostAmazon RedshiftINSERT statementsare compatible with BigQuery. The following table shows exceptions.
| Amazon Redshift | BigQuery |
|---|---|
INSERT INTO table (column1 [, ...]) | INSERT [INTO] table (column1 [, ...]) |
INSERT INTO table (column1, [,...]) VALUES ( | INSERT [INTO] table (column1, [,...]) |
BigQuery also supports inserting values using a subquery (where one of thevalues is computed using a subquery), which is not supported in Amazon Redshift. Forexample:
INSERTINTOtable(column1,column2)VALUES('value_1',(SELECTcolumn2FROMtable2))COPY statement
Amazon Redshift'sCOPYcommandloads data into a table from data files or from an Amazon DynamoDB table.BigQuery does not use theSQL COPY command to load data,but you can use any of several non-SQL tools and options toload data into BigQuery tables.You can also use data pipeline sinks provided inApache SparkorApache Beamto write data into BigQuery.
UPDATE statement
Most Amazon RedshiftUPDATE statements are compatible with BigQuery. The followingtable shows exceptions.
| Amazon Redshift | BigQuery |
|---|---|
UPDATE table | UPDATE tableNote: All UPDATE statements in BigQuery require aWHERE keyword,followed by a condition. |
UPDATE table | UPDATE tableNote: BigQuery's UPDATE command does not supportDEFAULT values.If the Amazon Redshift UPDATE statement does not include aWHERE clause, theBigQueryUPDATE statement should be conditionedWHERE TRUE. |
DELETE andTRUNCATE statements
TheDELETE andTRUNCATE statements are both ways to remove rows from a tablewithout affecting the table schema or indexes.
In Amazon Redshift, theTRUNCATE statement is recommended over anunqualifiedDELETE statement because it isfaster and does not requireVACUUM andANALYZE operations afterward.However, you can useDELETE statements to achieve the same effect.
In BigQuery, theDELETE statement must have aWHERE clause. For moreinformation aboutDELETE in BigQuery, see theBigQueryDELETE examplesin the DML documentation.
| Amazon Redshift | BigQuery |
|---|---|
DELETE[FROM] table_nameTRUNCATE[TABLE] table_name | DELETE FROM table_nameBigQuery DELETE statements require aWHERE clause. |
DELETE FROM table_name | DELETE FROM table_nameDELETE FROM table_nameIn Amazon Redshift, USING allows additional tables to be referenced in theWHERE clause. This can be achieved in BigQuery by using a subquery intheWHERE clause. |
MERGE statement
TheMERGE statement can combineINSERT,UPDATE,andDELETE operations into asingle upsert statement and perform the operations atomically. TheMERGEoperation must match at most one source row for each target row.
Amazon Redshift does not support a singleMERGE command. However, amerge operationcan be performed in Amazon Redshift by performingINSERT,UPDATE, andDELETE operationsin a transaction.
Merge operation by replacing existing rows
In Amazon Redshift, an overwrite of all of the columns in the target table can beperformed using aDELETE statement and then anINSERT statement. TheDELETEstatement removes rows that should be updated, and then theINSERT statementinserts the updated rows. BigQuery tables are limited to1,000 DML statementsper day, so you should consolidateINSERT,UPDATE, andDELETEstatements into asingleMERGE statement as shown in the following table.
| Amazon Redshift | BigQuery |
|---|---|
SeePerforming amerge operation byreplacingexisting rows.CREATE TEMP TABLE temp_table; | MERGE targetNote: All columns must be listed if updating all columns. |
SeePerforming amerge operation byspecifying acolumn list.CREATE TEMP TABLE temp_table; | MERGE target |
DDL syntax
This section addresses differences in data definition language syntax betweenAmazon Redshift and BigQuery.
SELECT INTO statement
In Amazon Redshift, theSELECT INTO statement can be used to insert the results of aquery into a new table, combining table creation and insertion.
| Amazon Redshift | BigQuery |
|---|---|
SELECT expression, ... INTO table | INSERT table |
WITH subquery_table AS ( SELECT ... | INSERT table |
SELECT expression | BigQuery offers several ways to emulate temporary tables. See thetemporary tables section for more information. |
CREATE TABLE statement
Most Amazon RedshiftCREATE TABLEstatements are compatible with BigQuery, except for the following syntax elements, whichare not used in BigQuery:
| Amazon Redshift | BigQuery |
|---|---|
CREATE TABLE table_name (Note: UNIQUE andPRIMARY KEY constraints areinformational andare notenforced by the Amazon Redshiftsystem. | CREATE TABLE table_name ( |
CREATE TABLE table_nameNote: UNIQUE andPRIMARY KEY constraints are informational andare notenforced by the Amazon Redshift system. | CREATE TABLE table_nameNote: BigQuery does not use UNIQUE,PRIMARY KEY, orFOREIGN KEY tableconstraints. To achieve similar optimization that these constraints provide during query execution,partition and cluster your BigQuery tables.CLUSTER BY supports up to4 columns. |
CREATE TABLE table_name | Referencethis example to learn how to usetheINFORMATION_SCHEMA tables to copy column names, data types, andNOT NULL constraints to a new table. |
CREATE TABLE table_nameNote: In Amazon Redshift, the BACKUPNO setting is specified to save processing time and reducestorage space. | TheBACKUP NO table option is not used or needed because BigQueryautomatically keeps up to 7 days of historical versions of all ofyour tables with no effect on processing time or billed storage. |
CREATE TABLE table_name | BigQuery supports clustering, which allows storing keys in sortedorder. |
CREATE TABLE table_name | CREATE TABLE table_name |
CREATE TABLE IF NOT EXISTS table_name ... | CREATE TABLE IF NOT EXISTS |
BigQuery also supports the DDL statementCREATE OR REPLACE TABLE,which overwrites a table if it already exists.
BigQuery'sCREATE TABLE statement also supports the following clauses, which donot have an Amazon Redshift equivalent:
For more information aboutCREATE TABLE in BigQuery, see theBigQueryCREATE TABLE examplesin the DML documentation.
Temporary tables
Amazon Redshift supports temporary tables, which are only visible within the currentsession. There are several ways to emulate temporary tables in BigQuery:
- Dataset TTL: Create a dataset that has a short time to live (forexample, one hour) so that any tables created in the dataset areeffectively temporary because they won't persist longer than the dataset'stime to live. You can prefix all of the table names in this dataset withtemp to clearly denote that the tables are temporary.
Table TTL: Create a table that has a table-specific short time to liveusing DDL statements similar to the following:
CREATETABLEtemp.name(col1,col2,...)OPTIONS(expiration_timestamp=TIMESTAMP_ADD(CURRENT_TIMESTAMP(),INTERVAL1HOUR));
CREATE VIEW statement
The following table shows equivalents between Amazon Redshift and BigQuery for theCREATE VIEW statement.
| Amazon Redshift | BigQuery |
|---|---|
CREATE VIEW view_name AS SELECT ...code> | CREATE VIEW view_name AS SELECT ... |
CREATE OR REPLACE VIEW view_name AS SELECT ... | CREATE OR REPLACE VIEW |
CREATE VIEW view_name | CREATE VIEW view_name AS SELECT... |
| Not supported. | CREATE VIEW IF NOT EXISTS cview_nameCreates a new view only if the view does not exist in the specified dataset. |
CREATE VIEW view_nameIn Amazon Redshift, a late binding view is required in order to reference anexternal table. | In BigQuery, to create a view, all referenced objects must alreadyexist. BigQuery allows you toquery external data sources. |
User-defined functions (UDFs)
A UDF lets you create functions for custom operations. These functions acceptcolumns of input, perform actions, and return the result of those actions as avalue.
Both Amazon Redshift and BigQuery support UDFs using SQL expressions. Additionally, inAmazon Redshift you can create aPython-based UDF,and in BigQuery you can create aJavaScript-based UDF.
Refer to theGoogle Cloud BigQuery utilities GitHub repository for a library of common BigQuery UDFs.
CREATE FUNCTION syntax
The following table addresses differences in SQL UDF creation syntax betweenAmazon Redshift and BigQuery.
| Amazon Redshift | BigQuery |
|---|---|
CREATE [ORREPLACE] FUNCTION | CREATE [OR REPLACE] FUNCTIONNote: In a BigQuerySQL UDF, a return data type isoptional. BigQuery infers the result type of the function from theSQL function body when a query calls the function. |
CREATE [ORREPLACE] FUNCTION | CREATE [OR REPLACE] FUNCTIONNote: Function volatility is not a configurable parameter inBigQuery. All BigQuery UDF volatility is equivalent to Amazon Redshift's IMMUTABLE volatility (that is, it does not do database lookups orotherwise use information not directly present in its argument list). |
CREATE [ORREPLACE] FUNCTIONNote: Amazon Redshift supports only a SQL SELECT clause as functiondefinition. Also, theSELECT clause cannot include any of theFROM,INTO, WHERE, GROUP BY, ORDER BY, andLIMIT clauses. | CREATE [OR REPLACE] FUNCTIONNote: BigQuery supports any SQL expressions as function definition.However, referencing tables, views, or models is not supported. |
CREATE [ORREPLACE] FUNCTION | CREATE [OR REPLACE] FUNCTIONfunction_name ([sql_arg_name sql_arg_data_type[,..]]) RETURNSdata_type AS sql_function_definitionNote: Language literal need not be specified in a GoogleSQL UDF.BigQuery interprets the SQL expression by default. Also, the Amazon Redshiftdollar quoting ( $$) is not supported in BigQuery. |
CREATE [ORREPLACE] FUNCTION function_name (integer, integer) RETURNSinteger IMMUTABLE AS $$ SELECT $1 + $2 $$ LANGUAGE sql | CREATE [OR REPLACE] FUNCTIONNote: BigQuery UDFs require all input arguments to be named. TheAmazon Redshift argument variables ( $1,$2, …) are not supported inBigQuery. |
CREATE [ORREPLACE] FUNCTIONNote: Amazon Redshift does not support ANY TYPE for SQL UDFs. However, itsupports using theANYELEMENT data type in Python-based UDFs. | CREATE [OR REPLACE] FUNCTIONNote: BigQuery supports using ANY TYPE as argument type. The functionaccepts an input of any type for this argument. For more information,seetemplated parameter in BigQuery. |
BigQuery also supports theCREATE FUNCTION IF NOT EXISTS statement, whichtreats the query as successful and takes no action if a function with the samename already exists.
BigQuery'sCREATE FUNCTION statement also supports creatingTEMPORARYorTEMP functions, which do not have an Amazon Redshift equivalent.
Seecalling UDFsfor details on executing a BigQuery-persistent UDF.
DROP FUNCTION syntax
The following table addresses differences inDROP FUNCTION syntax betweenAmazon Redshift and BigQuery.
| Amazon Redshift | BigQuery |
|---|---|
DROPFUNCTION | DROP FUNCTIONNote: BigQuery does not require using the function's signature fordeleting the function. Also, removing function dependencies is notsupported in BigQuery. |
BigQuery also supports theDROP FUNCTION IF EXISTS statement,which deletes the function only if the function exists in the specifieddataset.
BigQuery requires that you specify theproject_nameif the function is not located in the current project.
UDF components
This section highlights the similarities and differences in UDF componentsbetween Amazon Redshift andBigQuery.
| Component | Amazon Redshift | BigQuery |
|---|---|---|
| Name | Amazon Redshiftrecommends using the prefix_ffor function names to avoid conflicts with existingor future built-in SQL function names. | In BigQuery, you can use any custom function name. |
| Arguments | Arguments are optional. You can use name and data types for PythonUDF arguments and only data types for SQL UDF arguments. In SQL UDFs,you must refer to arguments using$1,$2,and so on. Amazon Redshift alsorestrictsthe number of arguments to 32. | Arguments are optional, but if you specify arguments, they must useboth name and data types for both JavaScript and SQL UDFs. Themaximum number of arguments for a persistent UDF is 256. |
| Data type | Amazon Redshift supports a different set of data types forSQLandPython UDFs. For a Python UDF, the data type might also be ANYELEMENT.You must specify a RETURNdata type for both SQL andPython UDFs.SeeData types in this document for equivalents between datatypes in Amazon Redshift and in BigQuery. | BigQuery supports a different set of data types forSQL andJavaScript UDFs. For a SQL UDF, the data type might also be ANY TYPE. Formore information, seetemplated parameters inBigQuery.The RETURNdata type is optional for SQL UDFs.SeeSupported JavaScript UDF data typesfor information on how BigQuery data types map to JavaScript datatypes. |
| Definition | For both SQL and Python UDFs, you must enclose the functiondefinition using dollar quoting, as in a pair of dollar signs($$), to indicate the start and end of the functionstatements.ForSQLUDFs, Amazon Redshift supports only a SQL SELECTclauseas the function definition. Also, theSELECT clausecannot include any of theFROM,INTO,WHERE,GROUPBY,ORDER BY, andLIMITclauses.ForPythonUDFs, you can write a Python program using thePython 2.7 StandardLibrary or import your custom modules by creating one using the CREATELIBRARYcommand. | In BigQuery, you need to enclose the JavaScript code in quotes. SeeQuotingrules for moreinformation. ForSQL UDFs, you can use any SQLexpressions as the function definition. However, BigQuery doesn'tsupport referencing tables, views, or models. ForJavaScript UDFs, you canincludeexternal code libraries directlyusing the OPTIONSsection. You can also use theBigQuery UDFtest tool to test your functions. |
| Language | You must use theLANGUAGEliteral to specify thelanguage as eithersqlfor SQL UDFs orplpythonufor Python UDFs. | You need not specifyLANGUAGEfor SQL UDFs but mustspecify the language asjsfor JavaScript UDFs. |
| State | Amazon Redshift does not support creating temporary UDFs. Amazon Redshift provides an option to define thevolatilityof a function using VOLATILE,STABLE,orIMMUTABLEliterals. This is used for optimization bythe query optimizer. | BigQuery supports both persistent and temporary UDFs. You can reusepersistent UDFs across multiple queries, whereas you can only usetemporary UDFs in a single query. Function volatility is not a configurable parameter in BigQuery. AllBigQuery UDF volatility is equivalent to Amazon Redshift's IMMUTABLEvolatility. |
| Security and privileges | To create a UDF, you must havepermissionfor usage on language for SQL or plpythonu (Python). By default,USAGE ON LANGUAGE SQLis granted toPUBLIC,but you must explicitly grantUSAGE ON LANGUAGE PLPYTHONUto specific users or groups.Also, you must be a superuser to replace a UDF. | Granting explicit permissions for creating or deleting any type ofUDF is not necessary in BigQuery. Any user assigned a role ofBigQuery Data Editor (havingbigquery.routines.*as one of the permissions)can create or delete functions for the specified dataset.BigQuery also supports creating custom roles. This can be managedusingCloud IAM. |
| Limits | SeePython UDFlimits. | Seelimits on user-defined functions. |
Metadata and transaction SQL statements
| Amazon Redshift | BigQuery |
|---|---|
SELECT * FROMSTL_ANALYZE WHERE name | Not used in BigQuery. You don't need to gather statistics in orderto improve query performance. To get information about your datadistribution, you can useapproximate aggregate functions. |
ANALYZE[[ table_name[(column_name | Not used in BigQuery. |
LOCKTABLE table_name; | Not used in BigQuery. |
BEGINTRANSACTION; SELECT ... | BigQuery uses snapshot isolation. For details, seeConsistency guarantees. |
EXPLAIN... | Not used in BigQuery. Similar features are thequery plan explanation in the BigQuery Google Cloud console, and inaudit logging in Cloud Monitoring. |
SELECT * FROMSVV_TABLE_INFO WHERE | SELECT * EXCEPT(is_typed) FROMFor more information seeIntroduction to BigQuery INFORMATION_SCHEMA. |
VACUUM[table_name] | Not used in BigQuery. BigQueryclustered tables are automatically sorted. |
Multi-statement and multi-line SQL statements
Both Amazon Redshift and BigQuery support transactions (sessions)and therefore support statements separated by semicolons that are consistentlyexecuted together. For more information, seeMulti-statement transactions.
Procedural SQL statements
CREATE PROCEDURE statement
| Amazon Redshift | BigQuery |
|---|---|
CREATE orREPLACE PROCEDURE | CREATE PROCEDURE if a name isrequired.Otherwise, use inline with BEGIN or in a single line withCREATE TEMP FUNCTION. |
CALL | CALL |
Variable declaration and assignment
| Amazon Redshift | BigQuery |
|---|---|
DECLARE | DECLAREDeclares a variable of the specified type. |
SET | SETSets a variable to have the value of the provided expression, or setsmultiple variables at the same time based on the result of multipleexpressions. |
Error condition handlers
In Amazon Redshift, an error encountered during the execution of a stored procedureends the execution flow, ends the transaction, and rolls back the transaction.These results occur because subtransactions are not supported. In anAmazon Redshift-stored procedure, the only supportedhandler_statementisRAISE. In BigQuery, errorhandling is a core feature of the main control flow, similar to what otherlanguages provide withTRY ... CATCH blocks.
| Amazon Redshift | BigQuery |
|---|---|
BEGIN ...EXCEPTION WHEN OTHERSTHEN | BEGIN ... EXCEPTION WHEN ERRORTHEN |
RAISE | RAISE |
[ <<label>> ] [ DECLARE declarations ] | BEGIN |
Cursor declarations and operations
Because BigQuery doesn't support cursors or sessions, the following statementsaren't used in BigQuery:
DECLAREcursor_nameCURSOR[FOR] ...PREPAREplan_name [ (datatype [, ...] ) ] AS statementOPENcursor_name FOR SELECT ...FETCH[ NEXT | ALL | {FORWARD [ count | ALL ] } ] FROM cursor_nameCLOSEcursor_name;
If you're using the cursor to return a result set, you can achieve similarbehavior usingtemporary tablesin BigQuery.
Dynamic SQL statements
Thescripting featurein BigQuery supports dynamic SQL statements like those shown in the followingtable.
| Amazon Redshift | BigQuery |
|---|---|
EXECUTE | EXECUTE IMMEDIATE |
Flow-of-control statements
| Amazon Redshift | BigQuery |
|---|---|
IF..THEN..ELSIF..THEN..ELSE..ENDIF | IF condition |
name CURSOR[ ( arguments ) ] FOR query | Cursors or sessions are not used in BigQuery. |
[< | LOOP |
WHILEcondition LOOP stmts END LOOP | WHILE condition |
EXIT | BREAK |
Consistency guarantees and transaction isolation
Both Amazon Redshift and BigQuery are atomic—that is, ACID-compliant on a per-mutationlevel across many rows.
Transactions
Amazon Redshift supportsserializable isolationby default for transactions. Amazon Redshift lets youspecifyany of the four SQL standard transaction isolation levels but processes allisolation levels as serializable.
BigQuery alsosupports transactions.BigQuery helps ensureoptimistic concurrency control(first to commit has priority) withsnapshotisolation,in which a query reads the last committed data before the query starts. Thisapproach guarantees the same level of consistency on a per-row, per-mutationbasis and across rows within the same DML statement, yet avoids deadlocks. Inthe case of multiple DML updates against the same table, BigQuery switches topessimistic concurrency control.Load jobs can run completely independently and append to tables.
Rollback
If Amazon Redshift encounters any error while running a stored procedure, it rollsback all changes made in a transaction. Additionally, you can use theROLLBACKtransaction control statement in a stored procedure to discard all changes.
In BigQuery, you can use theROLLBACK TRANSACTION statement.
Database limits
Check theBigQuery public documentationfor the latest quotas and limits. Many quotas for large-volume users can beraised by contacting the Cloud support team. The following table shows acomparison of the Amazon Redshift and BigQuery database limits.
| Limit | Amazon Redshift | BigQuery |
|---|---|---|
| Tables in each database for large and xlarge cluster node types | 9,900 | Unrestricted |
| Tables in each database for 8xlarge cluster node types | 20,000 | Unrestricted |
| User-defined databases you can create for each cluster | 60 | Unrestricted |
| Maximum row size | 4 MB | 100 MB |
Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2025-12-15 UTC.