Sélective Prédicat Déroulant Pour Afficher

0

La question

J'ai une grande colonne de la table de banque qui reçoit des mises à jour fréquentes. Je n'ai pas ingérer les mises à jour directement dans la table source, parce que cela créerait, dans la plupart des cas, un petit nombre de mises à jour à cause d'une table pleine de micro reconstruction de partition. Au lieu de cela j'flux de mises à jour d'une table de mise à jour, et au moment de la requête-je combiner les deux. Dans la pratique, cela fonctionne bien.

Afin de simplifier les choses, je vais jeter ce en vue users_view.

CREATE OR REPLACE VIEW users_view AS (
    SELECT * FROM users
    UNION ALL 
    SELECT * FROM user_changes
    QUALIFY ROW_NUMBER() OVER(
        PARTITION BY id 
        ORDER BY last_updated_at DESC
    ) = 1
)

À la fois la users table et user_changes table ont le même schéma ainsi que les quelques-uns configuration de la partition. De cette façon, je peux utiliser le prédicat de refoulement sur le point de vue de sélectionner uniquement les utilisateurs dans la bonne partition. Disons que c'est le account_id.

SELECT * FROM users_view
WHERE account_id = 1234

Mais l' users le tableau est un peu plus grand que la user_changes table, et j'aimerais pousser encore plus les prédicats jusqu'à la users table sans pousser supplémentaire prédicats jusqu'à la user_changes table. Pourquoi? Parce que d'appariement sur le users la table, tandis que 98% de précision, il a des faux positifs/négatifs. Les détails de l' user_changes pour mettre les pendules à l'heure. Ce que cela ressemblerait à l'extérieur d'un point de vue est ceci:

SELECT * FROM (
    SELECT * FROM users
    WHERE account_id = 1234 AND city = 'Chicago'
    UNION ALL 
    SELECT * FROM user_changes
    WHERE account_id = 1234
    QUALIFY ROW_NUMBER() OVER(
        PARTITION BY id 
        ORDER BY last_updated_at DESC
    ) = 1
)
WHERE account_id = 1234 AND city = 'Chicago'

Aussi désagréable que cela ressemble, il est beaucoup plus performant. Toutes les conditions peuvent être appliquées à la beaucoup plus grande users de la table, mais seulement immuable conditions peuvent être appliquées à la users_changes table. c'est à dire qu'Un utilisateur peut changer les villes, mais un utilisateur ne peut pas modifier les comptes. La deuxième exécution de toutes les conditions, après que l'union est d'attraper tous les changements que l' user_changes introduit.

C'est fastidieux à écrire, et plus encore pour la requête devient compliqué de requête et de constructeurs de s'impliquer. Donc, je suis à la recherche de façon à convaincre le sql planificateur de sauter prédicat de refoulement de certains prédicats sur mon user_changes tableau sans avoir besoin de formater la requête de ce type. Idéalement avec une vue.

PSEUDO SQL. PSEUDO SQL. PSEUDO SQL

Dans mes rêves les plus fous, je pourrais dire que le planificateur de requête où il peut utiliser la partition de prédicats, et où il peut utiliser non de la partition de prédicats.

CREATE OR REPLACE VIEW users_view AS (
    SELECT * FROM (
        SELECT * FROM users
        %PARTITION_PREDICATES%
        %NON_PARTITION_PREDICATES%

        UNION ALL 

        SELECT * FROM user_changes
        %PARTITION_PREDICATES%

        QUALIFY ROW_NUMBER() OVER(
            PARTITION BY id 
            ORDER BY last_updated_at DESC
        ) = 1
    )
    %PARTITION_PREDICATES%
    %NON_PARTITION_PREDICATES%
)

SELECT * FROM users_view
WHERE account_id = 1234 AND city = 'Chicago'

Toutes les idées folles?

1

La meilleure réponse

1

vous pouvez ajouter des colonnes supplémentaires src pour la détermination de la table source et enveloppez-les prédicats dans le CAS:

select * from
(
SELECT u.*, 'users' as src FROM users u
union all
SELECT uc.*, 'users_changes' as src FROM users_changes uc
) 
WHERE --applied only to users
      case when src  = 'users' 
                 then city = 'Chicago' --predicate wrapped in case
           else true
       end
  --applied to all
  AND account=12345 
2021-11-23 14:58:40

Idée très cool! Merci!!!!
micah

@michée vous pouvez envelopper tous les prédicats dans le seul CAS à l'aide de ET ou OU: then city = 'Chicago' AND one_more_condition AND some_other_condition
leftjoin

Dans d'autres langues

Cette page est dans d'autres langues

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................