SnowConvert AI - ANSI SQL - Sous-requêtes¶
Description¶
Une sous-requête est une requête dans une autre requête. Sous-requêtes dans une clause FROM ou [WHERE(https://docs.snowflake.com/en/sql-reference/constructs/where) est utilisée pour fournir des données qui seront utilisées pour limiter ou comparer/évaluer les données renvoyées par la requête les contenant. (Documentation des sous-requêtes Snowflake).
Les sous-requêtes peuvent être corrélées/non corrélées ainsi que scalaires/non scalaires.
Les sous-requêtes corrélées font référence aux colonnes de la requête externe. Dans Snowflake, des sous-requêtes corrélées s’exécutent pour chaque ligne de la requête. En revanche, les sous-requêtes non corrélées ne font pas référence à la requête externe et sont exécutées une fois pour la requête entière.
Les sous-requêtes scalaires renvoient une seule valeur comme résultat, sinon la sous-requête est non scalaire.
Les modèles suivants sont basés sur ces catégories.
Modèles d’échantillons de sources¶
Données de configuration¶
Teradata¶
CREATE TABLE tableA
(
col1 INTEGER,
col2 VARCHAR(20)
);
CREATE TABLE tableB
(
col3 INTEGER,
col4 VARCHAR(20)
);
INSERT INTO tableA VALUES (50, 'Hey');
INSERT INTO tableA VALUES (20, 'Example');
INSERT INTO tableB VALUES (50, 'Hey');
INSERT INTO tableB VALUES (20, 'Bye');
Snowflake¶
CREATE OR REPLACE TABLE tableA
(
col1 INTEGER,
col2 VARCHAR(20)
)
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "12/02/2024", "domain": "test" }}'
;
CREATE OR REPLACE TABLE tableB
(
col3 INTEGER,
col4 VARCHAR(20)
)
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "12/02/2024", "domain": "test" }}'
;
INSERT INTO tableA
VALUES (50, 'Hey');
INSERT INTO tableA
VALUES (20, 'Example');
INSERT INTO tableB
VALUES (50, 'Hey');
INSERT INTO tableB
VALUES (20, 'Bye');
Sous-requêtes non scalaires¶
Les sous-requêtes non scalaires spécifiées dans des opérateurs de sous-requête (ANY/ALL/IN/EXISTS) sont pris en charge.
Les sous-requêtes non scalaires utilisées comme tables dérivées sont également prises en charge.
Teradata¶
SELECT col2
FROM tableA
WHERE col1 IN (SELECT col3 FROM tableB);
SELECT col2
FROM tableA
WHERE col1 >= ALL(SELECT col3 FROM tableB);
SELECT col2, myDerivedTable.col4
FROM tableA, (SELECT * FROM tableB) AS myDerivedTable
WHERE col1 = myDerivedTable.col3;
Résultat¶
+---------+
| col2 |
+---------+
| Example |
+---------+
| Hey |
+---------+
+---------+
| col2 |
+---------+
| Hey |
+---------+
+---------+------+
| col2 | col4 |
+---------+------+
| Example | Bye |
+---------+------+
| Hey | Hey |
+---------+------+
Snowflake¶
SELECT
col2
FROM
tableA
WHERE col1 IN (
SELECT
col3 FROM
tableB
);
SELECT
col2
FROM
tableA
WHERE col1 >= ALL(
SELECT
col3 FROM
tableB
);
SELECT
col2,
myDerivedTable.col4
FROM
tableA, (
SELECT
* FROM
tableB
) AS myDerivedTable
WHERE col1 = myDerivedTable.col3;
Résultats¶
+---------+
| col2 |
+---------+
| Example |
+---------+
| Hey |
+---------+
+---------+
| col2 |
+---------+
| Hey |
+---------+
+---------+------+
| col2 | col4 |
+---------+------+
| Example | Bye |
+---------+------+
| Hey | Hey |
+---------+------+
Problèmes connus¶
1. Sous-requêtes avec FETCH d’abord qui ne sont pas des sous-requêtes scalaires non corrélées
Oracle permet d’utiliser la clause FETCH dans les sous-requêtes, Snowflake n’autorise l’utilisation de cette clause que si la sous-requête n’est pas scalaire non corrélée, sinon une exception sera générée.
SnowConvert AI marquera toute utilisation non valide de FETCH dans les sous-requêtes avec SSC-EWI-0108
Oracle :
-- Correlated scalar
SELECT col2
FROM tableA
WHERE col2 = (SELECT col4 FROM tableB WHERE col3 = col1 FETCH FIRST ROW ONLY);
-- Uncorrelated scalar
SELECT col2
FROM tableA
WHERE col2 = (SELECT col4 FROM tableB FETCH FIRST ROW ONLY);
Snowflake :
-- Correlated scalar
SELECT col2
FROM
tableA
WHERE col2 =
--** SSC-FDM-0002 - CORRELATED SUBQUERIES MAY HAVE SOME FUNCTIONAL DIFFERENCES. **
!!!RESOLVE EWI!!! /*** SSC-EWI-0108 - THE FOLLOWING SUBQUERY MATCHES AT LEAST ONE OF THE PATTERNS CONSIDERED INVALID AND MAY PRODUCE COMPILATION ERRORS ***/!!! (SELECT
ANY_VALUE( col4) FROM
tableB
WHERE col3 = col1
FETCH FIRST 1 ROW ONLY);
-- Uncorrelated scalar
SELECT col2
FROM
tableA
WHERE col2 = (SELECT col4 FROM
tableB
FETCH FIRST 1 ROW ONLY);