2017-05-04 1 views
1

Je suis confronté à un défi que je ne peux tout simplement pas maîtriser avec mes compétences SQL limitées. J'espère que vous pouvez m'aider. Étant donné que j'ai un tableau avec les prix des articles qui sont valables pour les clients spéciaux dans les délais spécifiés. Parce que parfois les gens ne pensent tout simplement pas avant d'entrer un nouveau prix sur une période de temps, je dois savoir, où il y a des périodes de chevauchement pour la combinaison de numéro d'article et numéro de client, j'ai juste besoin de savoir s'il y a un chevauchement se poursuit, pas quand le chevauchement se produit.Trouver des chevauchements dates de validité des prix dans SQL

J'ai une table CustomerPrices avec des données comme ça:

Item No Customer No  Valid from Valid to  Price 
12345  55544   01.01.2016 31.05.2016 5,66 
12345  55544   01.03.2017 01.06.2017 4,55 
12345  55544   01.02.2017 01.07.2017 6,41 

Pourriez-vous s'il vous plaît me pointer dans la bonne direction?

Meilleures salutations et merci!

+1

Quels sont vos dbms? –

+0

J'utilise SSMSE! – Kami

Répondre

0

Si vous avez juste besoin des paires client/article avec un chevauchement, puis:

select distinct custno, itemno 
from customerprices cp 
where exists (select 1 
       from customerprices cp2 
       where cp2.custno = cp.custno and cp2.itemno = cp.itemno and 
        cp2.validfrom <= cp.validto and 
        cp2.validto >= cp.validto and 
        (cp2.validfrom <> cp.validfrom or cp2.validto <> cp.validto) 
      ); 

Quelle est cette logique? Tout d'abord, il suppose qu'il n'y a pas de doublons complets sur le calendrier. Deuxièmement, il vérifie s'il y a chevauchement - y compris les périodes de fin. Cela devrait gérer tout chevauchement (ABBA, ABAB).

+0

C'était exactement ce dont j'avais besoin! Merci beaucoup! – Kami

0
select 
    itemno, 
    custno, 
    validfrom, 
    validto, 
    price 
from 
    CustomerPrices a 
where 
    exists (
     select 1 
     from CustomerPrices b 
     where 
      a.itemno = b.itemno 
      and a.custno = b.custno 
      and ((a.validfrom between b.validfrom and b.validto) 
       or (a.validto between b.validfrom and b.validto)) 
    ) 
0

Vous pouvez CONVERTIR des entrées de type date en une représentation entière (voir here). Cela vous permettra de comparer vos entrées de date plus facilement.

+0

Pouvez-vous s'il vous plaît expliquer? La comparaison de dates dans les dbms compatibles est à peu près la même que la comparaison d'entiers. Vous utilisez la même syntaxe et tout. Je pense que la conversion du type de données explicitement est juste des cycles gaspillés pendant le codage et l'exécution. –

+0

Pensé que ce serait plus facile de comparer avec une sous-requête, les résultats EXISTS offerts sont meilleurs. –

0

Vous ne savez pas quelle sortie vous recherchez? Expliquez la sortie.

IT retourne la dernière ligne parce que sa valeur de from se chevauche avec la ligne précédente validto.

declare @t table(id int identity(1,1),ItemNo int,CustomerNo int 
,Validfrom date,Validto date,Price int) 
insert into @t VALUES 
(12345,55544, '2016-01-01','2016-05-31',566) 
,(12345,55544,'2017-03-01','2017-06-01',455) 
,(12345,55544,'2017-02-01','2017-07-01',641) 
select t1.* 

from @t t 
inner join @t t1 
on t.ItemNo=t1.ItemNo 
and t.CustomerNo=t1.CustomerNo 
where 
(t1.Validfrom<t.Validto) 
and t1.id-t.id=1