2
votes

Pourquoi ma sous-requête fonctionne-t-elle avec une chaîne, mais pas une référence de champ?

J'ai (ce que je pense être) une requête assez complexe. La requête obtient l'enregistrement souhaité, puis toutes les données référencées dans la première réponse. Cela fonctionne si ma sous-requête conditionnelle est une chaîne, mais pas si c'est un champ (de la même valeur exacte).

SELECT 
     e1.entity as entity
    ,ARRAY_CAT(
      ARRAY_COMPACT( 
        ARRAY_CONSTRUCT( 
          any_value(e2.entity), 
          any_value(u1.user) 
        )
      )
      ,ARRAY_AGG(e3.entity)
    ) as includes
FROM ENTITIES e1
LEFT JOIN ENTITIES e2 ON e1.entity:owner:workspace = e2.entity:id
LEFT JOIN USERS u1 ON e1.entity:owner:user = u1.user:id
LEFT JOIN ENTITIES e3 ON e3.entity:id IN (
  SELECT ee2.value FROM 
  table(FLATTEN( input=> 
    SELECT SPLIT(LISTAGG( CASE WHEN IS_ARRAY(ee1.value:id) THEN ARRAY_TO_STRING(ee1.value:id, ',') ELSE ee1.value:id END, ','), ',') 
    FROM table(FLATTEN( input => ( SELECT e4.entity:relationships:entities FROM ENTITIES e4 WHERE e4.entity:id = e1.entity:id ) )) ee1
  )) ee2
)
GROUP BY e1.entity

Ce qui précède produit:

"entité "colonne: https://jsonblob.com/6d98b587-8989-11e9-b738-a9487a0dac0b

Colonne "comprend": https://jsonblob.com/068a8672-8988-11e9-b738-77f0e471310b

Cependant, si je change la chaîne uuid ( bd265f29-ca32-449a-b765-bb488e4d6b3c ) en e1.entity: id (ci-dessous) alors j'obtiens l'erreur Erreur de compilation SQL: le type de sous-requête non pris en charge ne peut pas être évalué .

// Query with string as conditional in lowest sub-query (4th line from the bottom)

SELECT 
     e1.entity as entity
    ,ARRAY_CAT(
      ARRAY_COMPACT( 
        ARRAY_CONSTRUCT( 
          any_value(e2.entity), 
          any_value(u1.user) 
        )
      )
      ,ARRAY_AGG(e3.entity)
    ) as includes
FROM ENTITIES e1
LEFT JOIN ENTITIES e2 ON e1.entity:owner:workspace = e2.entity:id
LEFT JOIN USERS u1 ON e1.entity:owner:user = u1.user:id
LEFT JOIN ENTITIES e3 ON e3.entity:id IN (
  SELECT ee2.value FROM 
  table(FLATTEN( input=> 
    SELECT SPLIT(LISTAGG( CASE WHEN IS_ARRAY(ee1.value:id) THEN ARRAY_TO_STRING(ee1.value:id, ',') ELSE ee1.value:id END, ','), ',') 
    FROM table(FLATTEN( input => ( SELECT e4.entity:relationships:entities FROM ENTITIES e4 WHERE e4.entity:id = 'bd265f29-ca32-449a-b765-bb488e4d6b3c' ) )) ee1
  )) ee2
)
GROUP BY e1.entity

Je n'ai aucune idée de la raison pour laquelle le commutateur est à l'origine de l'erreur. Pourquoi ma sous-requête fonctionne-t-elle avec une chaîne, mais pas une référence de champ?


1 commentaires

Dans la première jointure à gauche, vous avez: ENTITÉS DE JOINT GAUCHE e2 ON e1.entity: owner: workspace = e2.entity: id Devrait-il être "Où e4.entity: id = e1.entity: owner: workspace"?


3 Réponses :


0
votes

La documentation sur les sous-requêtes de Snowflake inclut cette restriction:

Les sous-requêtes scalaires corrélées ne sont actuellement prises en charge que si elles peuvent être statiquement déterminées pour renvoyer une ligne (par exemple, si la liste SELECT contient une fonction d'agrégation sans GROUP BY).

Vous pouvez donc essayer:

( SELECT MAX(e4.entity:relationships:entities)
  FROM ENTITIES e4
  WHERE e4.entity:id = e1.entity:id
)


1 commentaires

Malheureusement, cela ne fonctionne pas et renvoie la même erreur.



0
votes

Avez-vous essayé de le diffuser comme ça?

e1.entity:id::string


1 commentaires

Oui j'ai. Je compare e1.entity: id à lui-même dans un résultat de jointure différent, donc le casting ne devrait pas être le problème ici.



0
votes

La documentation Snowflake mentionne:

Les sous-requêtes avec une corrélation à l'intérieur de FLATTEN sont actuellement non pris en charge.

Ne pouvez-vous pas simplement utiliser e1.entity: relations: entités au lieu de la sous-requête?


1 commentaires

Non, car les relations sont filtrées vers un ensemble plus petit.