Standard SQL alternative to Oracle DECODE
A CASE expression is the ANSI SQL method, of which there are 2 varieties, "simple" and "searched":
1) Simple CASE expression:
CASE col WHEN 1 THEN 'One'
WHEN 2 THEN 'Two'
ELSE 'More'
END
2) Searched CASE expression:
CASE WHEN col < 0 THEN 'Negative'
WHEN col = 0 THEN 'Zero'
ELSE 'Positive'
END
CASE vs. DECODE
As always with Oracle ... AskTom...
From this post...
Decode is somewhat obscure -- CASE is
very very clear. Things that are
easy to do in decode are easy to do in
CASE, things that are hard or near
impossible to do with decode are easy
to do in CASE. CASE, logic wise, wins
hands down.
From a performance point of view seems they are about the same, again above article mentions some speed differences but without benchmarking the particular statements it's hard to say.
DECODE( ) function in SQL Server
You could use the 'CASE .. WHEN .. THEN .. ELSE .. END' syntax in SQL.
How to implement generic Oracle DECODE function in BigQuery?
Below is for BigQuery Standard SQL
CREATE TEMP FUNCTION DECODE(expr ANY TYPE, map ANY TYPE, `default` ANY TYPE ) AS ((
IFNULL((SELECT result FROM UNNEST(map) WHERE search = expr), `default`)
));
You can see how it works using below example
#standardSQL
CREATE TEMP FUNCTION DECODE(expr ANY TYPE, map ANY TYPE, `default` ANY TYPE ) AS ((
IFNULL((SELECT result FROM UNNEST(map) WHERE search = expr), `default`)
));
WITH `project.dataset.inventories` AS (
SELECT 1 product_id, 4 warehouse_id UNION ALL
SELECT 2, 2 UNION ALL
SELECT 3, 5
)
SELECT product_id, warehouse_id,
DECODE(warehouse_id,
[STRUCT<search INT64, result STRING>
(1,'Southlake'),
(2,'San Francisco'),
(3,'New Jersey'),
(4,'Seattle')
], 'Non domestic') AS `Location_of_inventory`
FROM `project.dataset.inventories`
with result
Row product_id warehouse_id Location_of_inventory
1 1 4 Seattle
2 2 2 San Francisco
3 3 5 Non domestic
Another example of use is:
#standardSQL
CREATE TEMP FUNCTION DECODE(expr ANY TYPE, map ANY TYPE, `default` ANY TYPE ) AS ((
IFNULL((SELECT result FROM UNNEST(map) WHERE search = expr), `default`)
));
WITH `project.dataset.inventories` AS (
SELECT 1 product_id, 4 warehouse_id UNION ALL
SELECT 2, 2 UNION ALL
SELECT 3, 5
), map AS (
SELECT 1 search, 'Southlake' result UNION ALL
SELECT 2, 'San Francisco' UNION ALL
SELECT 3, 'New Jersey' UNION ALL
SELECT 4, 'Seattle'
)
SELECT product_id, warehouse_id,
DECODE(warehouse_id, kv, 'Non domestic') AS `Location_of_inventory`
FROM `project.dataset.inventories`,
(SELECT ARRAY_AGG(STRUCT(search, result)) AS kv FROM map) arr
with the same output
Update to address - "for a reusable UDF, not having to name the fields makes it closer to Oracle's implementation."
CREATE TEMP FUNCTION DECODE(expr ANY TYPE, map ANY TYPE, `default` ANY TYPE ) AS (
IFNULL((
SELECT result FROM (
SELECT NULL AS search, NULL AS result UNION ALL SELECT * FROM UNNEST(map)
)
WHERE search = expr
), `default`)
);
So now - previous examples can be used w/o explicit naming fields as in example below
#standardSQL
CREATE TEMP FUNCTION DECODE(expr ANY TYPE, map ANY TYPE, `default` ANY TYPE ) AS (
IFNULL((
SELECT result FROM (
SELECT NULL AS search, NULL AS result UNION ALL SELECT * FROM UNNEST(map)
)
WHERE search = expr
), `default`)
);
WITH `project.dataset.inventories` AS (
SELECT 1 product_id, 4 warehouse_id UNION ALL
SELECT 2, 2 UNION ALL
SELECT 3, 5
)
SELECT product_id, warehouse_id,
DECODE(warehouse_id,
[ (1,'Southlake'),
(2,'San Francisco'),
(3,'New Jersey'),
(4,'Seattle')
], 'Non domestic') AS `Location_of_inventory`
FROM `project.dataset.inventories`
still with same output as before
Decode equivalent in postgres
There is an equivalent. It's called a CASE
statement.
There are two forms of CASE:
Simple CASE:
CASE search-expression
WHEN expression [, expression [ ... ]] THEN
statements
[ WHEN expression [, expression [ ... ]] THEN
statements
... ]
[ ELSE
statements ]
END CASE;
Searched CASE:
CASE
WHEN boolean-expression THEN
statements
[ WHEN boolean-expression THEN
statements
... ]
[ ELSE
statements ]
END CASE;
CASE
statements are easier to read; I prefer these over decode()
in Oracle.
Oracle decode equivalent function to Postgres
You could use a standard case
expression:
order by case pts.process_status
when 'PTSPS_INPROGRESS' then 1
when 'PTSPS_SUBMITTED' then 2
when 'PTSPS_DRAFT' then 3
when 'PTSPS_REJECTED' then 4
when 'PTSPS_APPROVED' then 5
end
Oracle SQL: Alternative to nested REPLACE() in Select statement?
A CASE expression would work for your example:
case ToiletType
when 'A' then 'Automatic Standard'
when 'P' then 'Portable Potty'
end
i.e.
SELECT IncidentNumber,
case ToiletType
when 'A' then 'Automatic Standard'
when 'P' then 'Portable Potty'
end as ToiletType,
ToiletDangers,
IncidentDate
FROM Core.LostLawsuits
Perhaps better though would be to join to a ToiletTypes table?
Related Topics
Sql Access Query- Update Row If Exists, Insert If Does Not
Date Split-Up Based on Fiscal Year
Sqlite: Alias Column Name Can't Contains a Dot "."
Why Can't I Reorder My SQL Server Columns
Recommended Method to Import a .Csv File into Microsoft SQL Server 2008 R2
Grouping by Date, Return Row Even If No Records Found
Best Way to Find SQL Locks in SQL Server 2008
How to Use a Variable in Oracle Script for The Table Name
Sql String Manipulation [Get All Text Left of '(']
T/F: Using If Statements in a Procedure Produces Multiple Plans
How to Get Get Unique Records Based on Multiple Columns from a Table
What Is Wrong with My Update Statement with a Join in Oracle
Oracle SQL to Sort Version Numbers
How to Relate 3 Tables Depending on Event
Is There a Tool to Generate a Full Database Ddl for SQL Server? What About Postgres and MySQL
Error: Subquery Must Return Only One Column
How to Get Current/Todays Date Data in SQL Server
Display Multiple Rows and Column Values into a Single Row, Multiple Column Values