Je dois renvoyer la dernière ligne disponible, mais sous certaines conditions. Étant donné que Hive ne prend pas en charge PL-T / SQL, je dois travailler sur des fonctions.
Le code actuel sélectionne uniquement le dernier enregistrement et ne prend pas en compte ACTIVE_F
.
MYUSER_INSERT_TIME ACTIVE_F 2019-03-06 15:54:22.000 0
Mes données:
MYUSER_INSERT_TIME ACTIVE_F 2019-06-14 15:00:32.000 6 2019-03-06 15:54:22.000 0 2019-01-25 08:43:45.000 1 2018-12-13 09:49:50.000 0 2018-11-24 10:11:06.000 0 2018-11-06 12:17:34.000 1 2018-07-04 16:59:15.000 0 2018-05-29 12:22:15.000 1 2018-05-24 20:19:00.000 2 2018-05-24 20:19:00.000 2
Comportement attendu:
Rechercher le dernier enregistrement (terminé)
Cochez ACTIVE_F (lorsque 6 - passez à la ligne suivante et renvoyez cette ligne, sinon passez à la ligne suivante)
Résultat souhaité:
WITH CTE AS (select ID, myuser_insert_time as insert_time, max(myuser_insert_time) OVER (PARTITION BY ID ORDER BY ID) as rn from tbl1) SELECT * FROM CTE WHERE rn = insert_time
3 Réponses :
Vous semblez simplement vouloir filtrer active_f = 6
, si je comprends bien. Vous devez le faire avant de calculer le temps maximum d'insertion; c'est-à-dire que dans le CTE:
with cte as ( select ID, myuser_insert_time as insert_time, row_number() over (partition by id order by (case when active_f = 6 then 2 else 1 end), myuser_insert_time desc ) as rn from tbl1 ) select * from CTE where rn = 1;
Votre max ()
avait également une colonne order by
, vous preniez donc un max () . Ce n'est pas nécessaire. L'ordre par
n'est pas nécessaire (même si le code a fonctionné).
EDIT:
Si vous avez besoin de "6" si c'est la seule ligne, alors utilisez row_number ()
et faites-en la dernière ligne:
with cte as ( select ID, myuser_insert_time as insert_time, max(myuser_insert_time) over (partition by ID) as max_myuser_insert_time from tbl1 where active_f <> 6 ) select * from CTE where myuser_insert_time = insert_time;
Malheureusement, éliminer 6
n'est pas une solution de contournement ici. Il peut y avoir un cas où une seule ligne existe - qui a 6
. S'il est le seul, il devrait être affiché.
@ marcin2x4. . . Je ne pense pas que ce soit clair dans la question.
Je vais réitérer. Je dois trouver la première dernière ligne qui apparaît après la ligne avec ACTIVE_F = 6
. Si la deuxième ligne est également 6
- continuez la boucle.
@ marcin2x4. . . C'est ce que fait le code édité.
order by (case when active_f = 6 then 2 else 1 end), myuser_insert_time DESC
- DESC
corrige le problème car j'ai besoin du dernier enregistrement (insérer l'heure) :)
Ajoutez case when active_f = 6 puis 1 else 0 end
à la clause order by
de la fonction analytique. Les enregistrements avec active_f! = 6 seront préférés. Utilisez également row_number et order by myuser_insert_time desc:
WITH CTE AS (select ID, myuser_insert_time as insert_time, row_number() OVER (PARTITION BY ID ORDER BY myuser_insert_time desc, case when active_f =6 then 1 else 0 end) as rn from tbl1) SELECT * FROM CTE WHERE rn = 1
Presque là. J'ai besoin de la deuxième dernière ligne.
Trier les lignes de manière conditionnelle par ACTIVE_F afin que les 6 prennent la suite de toutes les autres valeurs
WITH CTE AS (select ID, myuser_insert_time as insert_time, row_number() OVER (PARTITION BY ID ORDER BY case ACTIVE_F when 6 then 1 else 0 end, eendmyuser_insert_time desc) as rn from tbl1) SELECT * FROM CTE WHERE rn = 1
Je pense que nous l'avons! Je vais tester sur des exemples de résultats et vous le faire savoir!
Cela fonctionne parfaitement! J'ai étendu CASE
dans ORDER BY
pour accueillir un indicateur supplémentaire qui doit être itéré à la deuxième place. ORDER BY case ACTIVE_F quand 6 puis 1 quand 0 puis 1 autre 0 fin, eendmyuser_insert_time desc
... de tbl1 où ACTIVE_F <> 6
?avez-vous une colonne dans la table à utiliser dans la clause
order by
?@Serg - Je ne peux pas simplement éliminer
6
car cela pourrait être le seul enregistrement dans certains cas.@Shu - oui,
MYUSER_INSERT_TIME