2010-09-08 5 views
0

tableA contient {id, fromPos not null, topos}Comment écrire une requête SQL pour savoir si une valeur se situe dans une plage

  • fromPos et topos indique une plage de valeurs pour une ligne particulière
  • topos est un champ nullable

et possède les valeurs suivantes

tableA (1, 5)  // means any position greater than or equal to 5 
tableA (2, 5, 10) // means any position between 5 and 10 (inclusive) 
tableA (3, 6) 
tableA (4, 7, 9) 
  • Comment chercher toutes les entrées dont la position est 7. Il devrait retourner les ID (1,2,3,4)
  • Comment chercher toutes les entrées dont la position est 5. Il devrait retourner les ID (1,2)
  • Comment récupérer toutes les entrées dont la position est 8. il doit retourner les ID (1,2,3,4)
+1

vous avez dit que la table (1, 5): la position supérieure à 5. Mais vous dites aussi que la récupération des entrées avec la position 5 devrait revenir 1, 2. N'est-ce pas contradictoire? –

+0

c'est inclusif, va changer les commentaires – user339108

+0

@Jonthan s'excuse fait une erreur. corrigé – user339108

Répondre

2

Pour une valeur cible donnée, X, la requête semble être:

SELECT id 
    FROM TableA 
WHERE fromPos <= X 
    AND (toPos >= X OR toPos IS NULL); 
0

en supposant que lorsqu'il n'y a pas topos mentionné dans votre exemple, il sera nulle.

1. Select * from tableA where fromPos <= 7 and (toPos=null or toPos >= 7) 
2. Select * from tableA where fromPos <= 5 and (toPos=null or toPos >= 5) 
3. Select * from tableA where fromPos <= 8 and (toPos=null or toPos >= 8) 
+2

Vous ne pouvez pas faire 'toPos = NULL' en SQL standard: vous devez utiliser 'toPos IS NULL'. –

+0

il peut utiliser SET ANSI_NULLS est OFF –

0
SELECT id 
    FROM <table> 
WHERE <value> BETWEEN fromPos AND COALESCE(toPos,99999999) 
+1

La table a reçu un nom et la solution générale ne doit pas tomber en panne lorsque la valeur recherchée est de cent millions ou plus. –

3
select * 
    from tableA t 
where t.fromPos <= requested_position 
    and coalesce(t.toPos, requested_position) >= requested_position 

Coalesce signifie que requested_position seront mis en comparaison si t.toPos semble être nulle, ainsi, une comparaison donnera toujours vrai et vous ne traiterez que t.fromPos <= requested_position

Ou, vous pouvez utiliser between pour une meilleure lisibilité, ce qui est le même:

select * 
    from tableA t 
where requested_position between t.fromPos and coalesce(t.toPos, requested_position) 
+0

Fonctionne bien, mais en utilisant ISNULL() ou COALESCE() dans les filtres où les grandes tables doit être évitée pour des raisons de performance http://weblogs.asp.net/stanleygu/archive/2010/02/08/solution- 5-implementation-paramètres-optionnels-dans-t-sql-stored-procedures.aspx – StuartLC

2
declare @position int 
set @position = 8 

select id from tablea 
where @position >= fromPos 
and (@position <= toPos or toPos is null) 


create table tableA 
(
id int not null, 
fromPos int not null, 
toPos int null 
) 

insert into dbo.tableA(id, fromPos) values (1, 5) 
insert into dbo.tableA(id, fromPos, toPos) values (2, 5, 10) 
insert into dbo.tableA(id, fromPos) values (3, 6) 
insert into dbo.tableA(id, fromPos, toPos) values (4, 7, 9) 
Questions connexes