Problème avec une requête simple pour find des dates dans SQL Server

J'utilise une requête simple pour get les dates du contrat pour une personne:

SELECT [KlienciUmowyDataPoczatkowa], IsNULL([KlienciUmowyDataKoncowa], GETDATE()) AS 'KlienciUmowyDataKoncowa' FROM [BazaZarzadzanie].[dbo].[KlienciPortfeleUmowy] WHERE [PortfelID] = 3 

C'est ce que je reçois:

 KlienciUmowyDataPoczatkowa KlienciUmowyDataKoncowa 2005-11-28 00:00:00.000 2008-07-22 00:00:00.000 2008-07-23 00:00:00.000 2010-03-09 15:45:42.457 

Le client signe un contrat qui a commencé le 2005-11-28, puis l'annexe a été signée, de sorte que son contrat actuel a pris fin le 22 juillet 2008 et qu'un nouveau contrat a commencé le 2008-07-23 et dure jusqu'à aujourd'hui (NULL converti en heure actuelle) . Il peut y avoir des clients avec beaucoup plus d'appendices, mais tout se passe comme ça.

My question is : Comment puis-je get un contrat qui est / était actif entre disons 2008-04-01 – 2008-06-30? Il est possible que le client entre cette période aura 2 ou même 5 appendices donc il devrait les returnner tous.

Aussi, je ne suis pas sûr s'il est nécessaire d'utiliser IsNull? Peut-être y a-t-il un meilleur moyen d'éviter l'utilisation d'IsNull et de saisir la date du jour comme rlocation.

MODIFIER:

Je pensais que cette solution de marc_s l'avait résolu mais il semble que ce ne fut pas le cas:

 SELECT [KlienciUmowyDataPoczatkowa], [KlienciUmowyDataKoncowa] FROM [BazaZarzadzanie].[dbo].[KlienciPortfeleUmowy] WHERE [PortfelID] = 3 AND [KlienciUmowyDataPoczatkowa] <= '2008-07-01' AND IsNULL([KlienciUmowyDataKoncowa], '99991231') >= '2008-09-30' 

Il renvoient 0 dates pour la période du 2008-07-01 au 2008-09-30 quand il devrait returnner les deux:

 2005-11-28 00:00:00.000 2008-07-22 00:00:00.000 2008-07-23 00:00:00.000 NULL 

Comme le client avait un contrat dans les deux cas.

EDIT2:

J'ai testé 2 requêtes proposées. Le premier pour les dates (20080401 – 20080630) comme dans l'exemple ci-dessous renvoie 1 ligne pour la 1ère requête (attendue), renvoie 0 lignes pour la 2ème requête (non attendu).

  SELECT [KlienciUmowyDataPoczatkowa], IsNULL([KlienciUmowyDataKoncowa], '99991231') AS 'KlienciUmowyDataKoncowa' FROM [BazaZarzadzanie].[dbo].[KlienciPortfeleUmowy] WHERE [PortfelID] = 3 AND [KlienciUmowyDataPoczatkowa] <= '20080401' AND IsNULL([KlienciUmowyDataKoncowa], '99991231') >= '20080630' SELECT [KlienciUmowyDataPoczatkowa], [KlienciUmowyDataKoncowa] FROM [BazaZarzadzanie].[dbo].[KlienciPortfeleUmowy] WHERE [PortfelID] = 3 AND -- either: start date is sometime between the two dates ([KlienciUmowyDataPoczatkowa] BETWEEN '20080401' AND '20080630' -- or: end date is sometime between the two dates OR ISNULL([KlienciUmowyDataKoncowa], GETDATE()) BETWEEN '20080401' AND '20080630') 

Deuxième test pour les dates '20080701' à '20080930' montre pour les résultats de la première requête 0 (pas prévu), et pour la 2ème requête 2 lignes (attendues).

  SELECT [KlienciUmowyDataPoczatkowa], IsNULL([KlienciUmowyDataKoncowa], '99991231') AS 'KlienciUmowyDataKoncowa' FROM [BazaZarzadzanie].[dbo].[KlienciPortfeleUmowy] WHERE [PortfelID] = 3 AND [KlienciUmowyDataPoczatkowa] <= '20080701' AND IsNULL([KlienciUmowyDataKoncowa], '99991231') >= '20080930' SELECT [KlienciUmowyDataPoczatkowa], [KlienciUmowyDataKoncowa] FROM [BazaZarzadzanie].[dbo].[KlienciPortfeleUmowy] WHERE [PortfelID] = 3 AND -- either: start date is sometime between the two dates ([KlienciUmowyDataPoczatkowa] BETWEEN '20080701' AND '20080930' -- or: end date is sometime between the two dates OR ISNULL([KlienciUmowyDataKoncowa], GETDATE()) BETWEEN '20080701' AND '20080930') 

EDIT3:

En utilisant la solution COMBINÉE des deux exemples, cela fonctionne pour les deux dates. Mais est-ce que ça ne me reviendra pas pour différentes dates? Des idées?

  SELECT [KlienciUmowyDataPoczatkowa] , ISNULL([KlienciUmowyDataKoncowa], GETDATE()) AS 'KlienciUmowyDataKoncowa' FROM [BazaZarzadzanie].[dbo].[KlienciPortfeleUmowy] WHERE [PortfelID] = 3 AND ( ([KlienciUmowyDataPoczatkowa] BETWEEN '20080401' AND '20080630' OR ISNULL([KlienciUmowyDataKoncowa], GETDATE()) BETWEEN '20080401' AND '20080630') OR ([KlienciUmowyDataPoczatkowa] <= '20080401' AND IsNULL([KlienciUmowyDataKoncowa], '99991231') >= '20080630') ) SELECT [KlienciUmowyDataPoczatkowa] , ISNULL([KlienciUmowyDataKoncowa], GETDATE()) AS 'KlienciUmowyDataKoncowa' FROM [BazaZarzadzanie].[dbo].[KlienciPortfeleUmowy] WHERE [PortfelID] = 3 AND ( ([KlienciUmowyDataPoczatkowa] BETWEEN '20080701' AND '20080930' OR ISNULL([KlienciUmowyDataKoncowa], GETDATE()) BETWEEN '20080701' AND '20080930') OR ([KlienciUmowyDataPoczatkowa] <= '20080701' AND IsNULL([KlienciUmowyDataKoncowa], '99991231') >= '20080930') ) 

Ma question est: Comment puis-je get un contrat qui est / était actif entre disons 2008-04-01 – 2008-06-30? Il est possible que le client entre cette période aura 2 ou même 5 appendices donc il devrait les returnner tous.

Fondamentalement, cela signifie:

  • la date de début de votre contrat doit être le ou avant le 2008-04-01
  • la date de fin de votre contrat doit être le ou après le 2008-06-30

Donc, vous avez besoin de quelque chose comme:

 SELECT (list of fields) FROM dbo.YourTable WHERE StartDate <= '20080401' AND EndDate >= '20080630' 

(ou quoi que ce soit en polonais 🙂

Vous n'aurez pas besoin d'ISNULL, sauf si l'une de vos dates peut être NULL (par exemple, EndDate = NULL signifie: contrat est valide jusqu'à révocation).

Dans ce cas, faites quelque chose comme:

 SELECT (list of fields) FROM dbo.YourTable WHERE StartDate <= '20080401' AND ISNULL(EndDate, '99991231') >= '20080630' 

Si le EndDate est NULL, prétendez que c'est le 31 décembre 9999 – cela devrait faire pour les deux mille prochaines années 🙂

METTRE À JOUR:
Pour votre mise à jour, essayez cette requête ici:

 SELECT [KlienciUmowyDataPoczatkowa], [KlienciUmowyDataKoncowa] FROM [BazaZarzadzanie].[dbo].[KlienciPortfeleUmowy] WHERE [PortfelID] = 3 AND -- either: start date is sometime between the two dates ([KlienciUmowyDataPoczatkowa] BETWEEN '20080701' AND '20080930' -- or: end date is sometime between the two dates OR ISNULL([KlienciUmowyDataKoncowa], GETDATE()) BETWEEN '20080701' AND '20080930') 

Est-ce que cela renvoie les résultats que vous attendez?

Je pense que cela fonctionnera. Si non, alors pouvez-vous être un peu plus clair et nous donner quelques exemples de lignes pour ce qui devrait et ne devrait pas être returnné.

 SELECT [KlienciUmowyDataPoczatkowa], IsNULL([KlienciUmowyDataKoncowa], GETDATE()) AS 'KlienciUmowyDataKoncowa' FROM [BazaZarzadzanie].[dbo].[KlienciPortfeleUmowy] WHERE [PortfelID] = 3 AND KlienciUmowyDataPoczatkowa] <= '2008-04-01' AND IsNULL([KlienciUmowyDataKoncowa], GETDATE()) >= '2008-06-30' 

Ou tu pourrais faire

 SELECT [KlienciUmowyDataPoczatkowa], IsNULL([KlienciUmowyDataKoncowa], GETDATE()) AS 'KlienciUmowyDataKoncowa' FROM [BazaZarzadzanie].[dbo].[KlienciPortfeleUmowy] WHERE [PortfelID] = 3 AND KlienciUmowyDataPoczatkowa] <= '2008-04-01' AND ([KlienciUmowyDataKoncowa] >= '2008-06-30' OR [KlienciUmowyDataKoncowa] IS NULL) 

Enfin, il semble que vous pourriez vouloir tous les contrats pour les clients qui ont eu au less 1 contrat actif entre ces dates. Si tel est le cas, faites ceci:

 SELECT [KlienciUmowyDataPoczatkowa], IsNULL([KlienciUmowyDataKoncowa], GETDATE()) AS 'KlienciUmowyDataKoncowa' FROM [BazaZarzadzanie].[dbo].[KlienciPortfeleUmowy] WHERE [PortfelID] = 3 AND <Client_ID> IN (SELECT <Client_ID> FROM [BazaZarzadzanie].[dbo].[KlienciPortfeleUmowy] WHERE [PortfelID] = 3 AND KlienciUmowyDataPoczatkowa] <= '2008-04-01' AND IsNULL([KlienciUmowyDataKoncowa], GETDATE()) >= '2008-06-30') 

Cela devrait get toutes vos lignes qui commencent ou se terminent au cours d'une période (Notez les variables @StartDate et @EndDate)

 SELECT [KlienciUmowyDataPoczatkowa] , ISNULL([KlienciUmowyDataKoncowa], GETDATE()) AS 'KlienciUmowyDataKoncowa' FROM [BazaZarzadzanie].[dbo].[KlienciPortfeleUmowy] WHERE [PortfelID] = 3 AND ([KlienciUmowyDataPoczatkowa] BETWEEN @StartDate AND @EndDate OR ISNULL([KlienciUmowyDataKoncowa], GETDATE()) BETWEEN @StartDate AND @EndDate) 

Si je comprends bien votre question, je suppose que vous pourriez utiliser quelque chose qui ressemble à ceci:

 SELECT [KlienciUmowyDataPoczatkowa], CASE WHEN [KlienciUmowyDataKoncowa] IS NULL THEN GETDATE() ELSE [KlienciUmowyDataKoncowa] END AS 'KlienciUmowyDataKoncowa' FROM [BazaZarzadzanie].[dbo].[KlienciPortfeleUmowy] WHERE [PortfelID] = 3 AND [KlienciUmowyDataPoczatkowa] BETWEEN @ContractDateStart AND @ContractDateEnd 

Où @ContractDateStart et @ContractDateEnd sont les valeurs paramétrées date de début et de fin du contrat respectivement de votre requête.