2011-09-21 4 views
1

Je crée une requête sur une base de données DB2, en me connectant via le pilote ODBC IBM Client Access. Je veux extraire des champs qui datent de moins de 6 jours, en fonction du champ 'a.ofbkddt' ... le problème est que ce champ n'est pas un champ date, mais plutôt un champ DECIMAL, formaté comme YYYYMMDD.Date arithmétique dans SQL sur DB2/ODBC

J'ai été capable de décomposer le champ décimal en l'enveloppant dans un appel à char(), puis en utilisant substr() pour extraire les champs de l'année, du mois et du jour. J'ai ensuite formaté cela comme une date, et appelé la fonction jours(), qui donne un nombre sur lequel je peux effectuer l'arithmétique.

Voici un exemple de la requête:

select 
     days(current date) - 
     days(substr(char(a.ofbkddt),1,4) concat '-'    -- YYYY- 
      concat substr(char(a.ofbkddt),5,2) concat '-'  -- MM- 
      concat substr(char(a.ofbkddt),7,2)) as difference, -- DD 
     a.ofbkddt as mydate 
from QS36F.ASDF a 

Cela donne les éléments suivants:

difference mydate 
2402  20050402 
2025  20060306 
... 
4   20110917 
3   20110918 
2   20110919 
1   20110920 

Voici ce que j'attends voir ... mais quand j'utilise la même logique dans le où clause de ma requête:

select 
     days(current date) - 
     days(substr(char(a.ofbkddt),1,4) concat '-'    -- YYYY- 
      concat substr(char(a.ofbkddt),5,2) concat '-'  -- MM- 
      concat substr(char(a.ofbkddt),7,2)) as difference, -- DD 
     a.ofbkddt as mydate 
from QS36F.ASDF a 
where 
(
days(current date) - 
days(substr(char(a.ofbkddt),1,4) concat '-'   -- YYYY- 
     concat substr(char(a.ofbkddt),5,2) concat '-' -- MM 
     concat substr(char(a.ofbkddt),7,2))   -- DD 
) < 6 

Je ne reçois aucun résultat de ma requête, même s'il est clair que je am obtenir des différences de date d'aussi peu que 1 jour (évidemment moins que les 6 jours que je demande dans la clause where). Mon premier réflexe était que le type de retour de days() ne soit pas un entier, provoquant l'échec de la comparaison ... d'après la documentation de days() trouvée à http://publib.boulder.ibm.com/iseries/v5r2/ic2924/index.htm?info/db2/rbafzmst02.htm, elle retourne un bigint. J'ai jeté la différence à l'entier, juste pour être sûr, mais cela n'a eu aucun effet.

Répondre

3

Vous allez à l'envers. Plutôt que d'utiliser une fonction sur chaque valeur unique de la table (vous pouvez donc la comparer à la date), vous devez précalculer la différence dans la date. Cela vous coûte des ressources pour exécuter la fonction sur chaque ligne - vous économiseriez beaucoup si vous pouviez le faire contre CURRENT_DATE (cela vous épargnerait peut-être encore plus si vous pouviez le faire avec votre code d'application, mais je me rends compte que cela pourrait pas possible). Vos dates sont dans un format triable, après tout.

La requête ressemble à ceci:

SELECT ofbkddt as myDate 
FROM QS36F.ASDF 
WHERE myDate > ((int(substr(char(current_date - 6 days, ISO), 1, 4)) * 10000) + 
       (int(substr(char(current_date - 6 days, ISO), 6, 2)) * 100) + 
       (int(substr(char(current_date - 6 days, ISO), 9, 2)))) 

qui, une fois exécuté sur votre échantillon datatable, les rendements suivants:

myDate 
============= 
20110917 
20110918 
20110919 
20110920 

Vous pouvez également regarder dans la création d'une table de calendrier, et ajoutez ces dates dans l'une des colonnes.

+0

Cela a fait l'affaire. –

1

Et si vous essayez un common table expression?

WITH A AS 
(
    select 
     days(current date) - 
     days(substr(char(a.ofbkddt),1,4) concat '-'    -- YYYY- 
      concat substr(char(a.ofbkddt),5,2) concat '-'  -- MM- 
      concat substr(char(a.ofbkddt),7,2)) as difference, -- DD 
     a.ofbkddt as mydate 
    from QS36F.ASDF a 
) 
SELECT 
    * 
FROM 
    a 
WHERE 
    difference < 6 
+0

Je l'aime vraiment ... c'est beaucoup plus propre ... mais il n'a pas retourné de lignes: -/ –

+0

Si vous supprimez la clause where, il retourne le même jeu de données que ci-dessus, oui? – billinkc

+0

Oui, il renvoie le même jeu de données que ci-dessus. Je suis déconcerté. –

0

Vos données ont-elles des zéros dans a.ofbkddt? Peut-être que cela provoque un comportement amusant dans la façon dont db2 évalue le moins que l'opération.