BTEQ scripts, stored procedures, and Teradata SQL parsed structurally. Converted to BigQuery SQL with native QUALIFY support. Proprietary functions, MERGE INTO, and PRIMARY INDEX logic fully translated.
Upload a BTEQ script, get converted code →BigQuery supports QUALIFY as a first-class SQL clause. Teradata's QUALIFY ROW_NUMBER(), RANK(), and DENSE_RANK() patterns transfer directly—no subquery wrapping, no CTE rewrite needed. The analytical intent stays clean and performant.
BTEQ's .LOGON, .IF/.THEN, .GOTO control flow and embedded SQL are parsed and converted to BigQuery scripting blocks with DECLARE, SET, IF/THEN/ELSE, and LOOP. .LABEL and .QUIT logic becomes structured exception handling in BigQuery procedures.
Teradata-specific functions like HASHROW, HASHBUCKET, NORMALIZE, EXPAND ON, and SAMPLE are mapped to BigQuery equivalents. BYTEINT, PERIOD, and INTERVAL data types are translated to BigQuery-native types. No proprietary runtime needed.
A BTEQ script using QUALIFY, SAMPLE, and MERGE INTO with Teradata-specific date arithmetic—converted to BigQuery SQL where QUALIFY is preserved and proprietary functions are mapped.
.LOGON tdserver/dbc,dbc;
COLLECT STATISTICS ON sales_data
COLUMN (store_id, sale_date);
SELECT store_id, sale_date, revenue,
product_category,
revenue - LAG(revenue) OVER (
PARTITION BY store_id
ORDER BY sale_date
) AS revenue_change
FROM sales_data
WHERE sale_date BETWEEN DATE - 90
AND DATE
QUALIFY RANK() OVER (
PARTITION BY store_id
ORDER BY revenue DESC
) <= 5;
MERGE INTO store_summary tgt
USING (
SELECT store_id,
SUM(revenue) AS total_rev,
COUNT(*) AS txn_count
FROM sales_data
WHERE sale_date >= DATE - 30
GROUP BY store_id
) src
ON tgt.store_id = src.store_id
WHEN MATCHED THEN UPDATE SET
total_revenue = src.total_rev,
txn_count = src.txn_count,
last_updated = CURRENT_DATE
WHEN NOT MATCHED THEN INSERT VALUES (
src.store_id, src.total_rev,
src.txn_count, CURRENT_DATE
);
.LOGOFF;
.QUIT;
-- BTEQ → BigQuery SQL
-- COLLECT STATISTICS: BigQuery manages
-- statistics automatically (no action needed)
SELECT store_id, sale_date, revenue,
product_category,
revenue - LAG(revenue) OVER (
PARTITION BY store_id
ORDER BY sale_date
) AS revenue_change
FROM `project.dataset.sales_data`
WHERE sale_date BETWEEN
DATE_SUB(CURRENT_DATE(), INTERVAL 90 DAY)
AND CURRENT_DATE()
QUALIFY RANK() OVER (
PARTITION BY store_id
ORDER BY revenue DESC
) <= 5;
MERGE INTO `project.dataset.store_summary` tgt
USING (
SELECT store_id,
SUM(revenue) AS total_rev,
COUNT(*) AS txn_count
FROM `project.dataset.sales_data`
WHERE sale_date >= DATE_SUB(
CURRENT_DATE(), INTERVAL 30 DAY)
GROUP BY store_id
) src
ON tgt.store_id = src.store_id
WHEN MATCHED THEN UPDATE SET
total_revenue = src.total_rev,
txn_count = src.txn_count,
last_updated = CURRENT_DATE()
WHEN NOT MATCHED THEN INSERT VALUES (
src.store_id, src.total_rev,
src.txn_count, CURRENT_DATE()
);
BTEQ control flow removed. QUALIFY preserved natively in BigQuery. DATE arithmetic mapped to DATE_SUB with INTERVAL. Table references become fully-qualified project.dataset.table. MERGE INTO syntax preserved with minor adjustments.
| Teradata Component | BigQuery Equivalent | Notes |
|---|---|---|
| BTEQ script | BigQuery scripting / procedure | .LOGON/.LOGOFF removed, SQL extracted and converted |
| QUALIFY clause | QUALIFY (native) | BigQuery supports QUALIFY natively—no rewrite |
| COLLECT STATISTICS | Automatic (not needed) | BigQuery manages optimizer statistics internally |
| PRIMARY INDEX | Partition + clustering | PARTITION BY date + CLUSTER BY for co-location |
| FastLoad | bq load / BigQuery DTS | Batch ingestion via CLI or Data Transfer Service |
| MultiLoad | MERGE INTO | Upsert and conditional update patterns |
| Stored Procedure | BigQuery procedure | SQL-based procedures with scripting blocks |
| Macro | Procedure + parameters | Reusable parameterized SQL blocks |
| SET table | SELECT DISTINCT / MERGE | Unique-row enforcement via deduplication |
| MERGE INTO | MERGE (native DML) | WHEN MATCHED / NOT MATCHED fully preserved |
| Temporal table | Time travel + snapshots | FOR SYSTEM_TIME AS OF for historical queries |
| TPump | BigQuery streaming insert | Storage Write API for near-real-time ingestion |
Data Matching compares Teradata output against BigQuery output—row by row, column by column. In the case study below, all BTEQ pipelines were validated with full production backtesting across 2,800 scripts.
See how Data Matching works →2,800 BTEQ scripts converted to BigQuery SQL. 900 QUALIFY clauses preserved natively without subquery wrapping. FastLoad and MultiLoad jobs replaced with bq load and BigQuery MERGE. PRIMARY INDEX strategies mapped to partitioning and clustering. Teradata appliance decommissioned within 90 days.
Read the full case study →Upload a BTEQ script or Teradata SQL file. Get parsed lineage, BigQuery SQL code, and a validation report.