0
votes

SQL - Obtenir la valeur null par défaut si les données ne sont pas disponibles

J'ai reçu des données de table comme suit:

SELECT 
   A.*
FROM TBL AS A 
WHERE A.ROW_NUM <= 6
UNION ALL
SELECT 
   B.*
FROM TBL AS B 
WHERE B.ROW_NUM NOT IN (SELECT ROW_NUM FROM TBL)
      AND B.ROW_NUM <= 6


6 commentaires

Les entrées avec row_num existent réellement pour le type_id s avec null créé_dt ?


Non, Row_num n'existe pas dans ce cas, j'ai besoin de créer Row_nums qui n'existe pas et que par défaut créé_dt à null et row_num par type_id est toujours <= 6


Juste pour être certain, row_num fait partie de la table, correct?


Je les générais à l'aide de Row_Number (), la table que j'ai posté est une table temporaire que je reçois après avoir utilisé la logique Row_Number ()


@Caitlan Jenner Toute aide s'il vous plaît?


Malheureusement, il n'y a pas de moyen simple de le faire dans une requête. Cela nécessite une logique de programmation. Je travaille sur une solution.


3 Réponses :


2
votes

Veuillez référencer l'autre réponse pour la manière dont vous pouvez faire cela à l'aide d'un jointure transversal - qui est assez soigné. Sinon, nous pouvons utiliser la logique de programmation disponible dans MS-SQL pour obtenir les résultats souhaités. L'approche suivante stocke distincte ID et type_id combinaisons dans un curseur SQL. Ensuite, il itière à travers les entrées du curseur afin de garantir que la quantité appropriée de données est stockée dans une table TEMP. Enfin, le SELECT est effectué sur la table TEMP et le curseur est fermé. Voici une preuve de concept que j'ai validé sur https://rexter.com/l/sql_server_online_compiler . xxx

Remarque, si vous avez une instance où une combinaison unique de ID et type_id est regroupée plus de 6 fois, les groupements supplémentaires sera inclus dans votre résultat final. Si vous ne devez afficher exactement 6 groupements, vous pouvez modifier cette partie de la requête à SELECT TOP 6 ... .


1 commentaires

Merci pour la réponse rapide



2
votes
  • En supposant que Row_num a au moins enregistrer a au moins les 6 rangées ... 1,2,3,4,5,6 en TBL et aucune fraction ou 0 ou chiffres négatifs ...
  • Nous obtenons une liste de tous les identifiants et ID de type distincts. (Alias ​​a)
  • Ensuite, nous obtenons une liste distincte de numéros de rangée inférieure à 7 (nous donnant 6 enregistrements)
  • Nous croisons les rejoindre pour vous assurer que chaque identifiant & type_id dispose de 6 lignes.
  • Nous avons ensuite quitté la réalisation de la base (TBL) pour obtenir toutes les dates nécessaires; lorsque de telles dates existent. Comme nous utilisons à gauche rejoindre les rangées avec une date persistera toujours.

    . xxx

    nous donnant: xxx

    testeur REX: Exemple

    Cela suppose également que vous voudriez 1-6 pour chaque combinaison de type_id et d'identifiant. Si l'ID n'est pas pertinent, alors excluez-la des critères de jointure. Je l'ai inclus comme c'est une pièce d'identité et on dirait que cela fait partie d'une clé.


4 commentaires

Le problème est que l'OP a dit que Row_Num ne fait pas naturellement partie de la table, et il est généré par la fonction Row_Number (). Vous pouvez toujours faire fonctionner cette technique si vous le prenez en compte, cependant. J'aime l'utilisation de rejoindre Cross Join - J'essayais d'abord et je ne pouvais pas le faire fonctionner.


Assez facile pour faire avec un 2nd CTE Obtenir la rangée ... puis utilisez le 2e CTE comme source ... L'intention est d'aider; Ne pas donner une solution complète: p La clé à ceci est que Row_num 1-6 doit exister dans les mêmes données pour au moins 1 enregistrement. Si non; Vous n'obtiendrez jamais 6 ... vous aurez le max disponible dans la table ..


Grand exemple! J'ai appris quelque chose de nouveau. Je quitte ma réponse depuis que j'ai passé un moment au travail, et cela présente une approche différente, bien que peut-être trop complexe, pour résoudre ce problème.


Je voudrais aussi. Il y a toujours plus d'un moyen. Et toutes les réponses ne fonctionnent pas dans tous les cas. Les alternatives peuvent donc aider les autres; C'est pourquoi j'ai posté cette réponse (espoir plus simple). J'ai aussi dû faire beaucoup d'hypothèses; que je pense que votre réponse n'a pas à faire



2
votes

Créer un CTE avec une série et une croix s'appliquent

   CREATE TABLE Test (
                            ID INT,
                            TYPE_ID INT,
                            CREATED_DT DATE  
                        )

    INSERT INTO Test(ID, TYPE_ID, CREATED_DT)
    VALUES
        (123,485,'2019-08-31')
        ,(123,485,'2019-05-31')
        ,(123,485,'2019-02-28')
        ,(123,485,'2018-11-30')
        ,(123,485,'2018-08-31')
        ,(123,485,'2018-05-31')
        ,(123,487,'2019-05-31')
        ,(123,487,'2018-05-31')
;


    WITH n(n) AS
    (
        SELECT 1
        UNION ALL
        SELECT n+1 FROM n WHERE n < 6
    )

    ,id_n as (
                SELECT 
                DISTINCT 
                ID
                ,TYPE_ID
                ,n

                FROM 
                Test
                cross apply n
             )

    SELECT 
        id_n.ID
        ,id_n.TYPE_ID
        ,test.CREATED_DT
        ,id_n.n row_num

    FROM 
        id_n 
        left join 
                    (
                        select 
                            ID
                            ,TYPE_ID
                            ,CREATED_DT

                            ,ROW_NUMBER() over(partition by id, type_id order by created_dt) rn 

                        from    
                        Test 

                    ) Test on Test.ID = id_n.ID and Test.TYPE_ID = id_n.TYPE_ID and id_n.n = test.rn


    drop table Test


0 commentaires