sacraj Ответов: 1

Запрос для поиска перекрывающихся десятичных диапазонов


Мне нужно выяснить перекрывающиеся десятичные диапазоны. Ниже приведена структура моей таблицы.

id FromValue  ToValue Condition
1   10           15    Between
2   16           NULL  Equals
3   6            9     Between
4   17           19    Between
5   16           NULL  Greater Than.



Когда я вставляю строку 5. Я не должен быть в состоянии вставить, потому что уже существует диапазон между 17 и 19. Когда я пытаюсь вставить больше 16, это не должно позволять.

То же самое условие применимо и к меньшему, чем условие. Если я попытаюсь вставить меньше 6. Он не должен позволять мне вставлять, потому что диапазон от 6 до 9 уже существует.

Пожалуйста, помогите мне с SQL-запросом.

[edit]добавлен блок кода-OriginalGriff [/edit]

Что я уже пробовал:

declare @fromValue decimal(18,5)
declare @toValue decimal(18,5)
select  * from RangeTest where  (fromValue is not null and toValue is not null  )  
and  ( (fromValue >= @fromValue and toValue =  @fromValue ))

CHill60

Логика проверки диапазонов не совсем ясна. Если бы вы могли объяснить, чего вы на самом деле пытаетесь достичь, или откуда вы получаете данные для вставки в таблицу?

1 Ответов

Рейтинг:
10

NightWizzard

В том, что вы пробовали, вы не учитываете, какой тип сравнения использовать в зависимости от столбца условий.

Я бы использовал INSTEAD OF INSERT триггер, чтобы проверить значение () и состояние, как, что:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE TRIGGER [dbo].[Check_Insert] 
   ON  [dbo].[RangeTest] 
  INSTEAD OF INSERT
AS 
BEGIN
	SET NOCOUNT ON;

	DECLARE @OK bit;
	DECLARE @FromValue int;
	DECLARE @ToValue int;
	DECLARE @Condition nvarchar(20);
    DECLARE curTest CURSOR LOCAL FAST_FORWARD FOR
		SELECT [FromValue]
			 , [ToValue]
			 , [Condition]
		 FROM inserted;

	OPEN curTest;

	WHILE (1 = 1)
		BEGIN
			FETCH NEXT FROM curTest INTO @FromValue, @ToValue, @Condition;

			IF (@@FETCH_STATUS <> 0)
				BREAK;

			SET @OK = 1;

			IF (@FromValue IS NOT NULL)
				BEGIN
					IF EXISTS(SELECT 1 
								FROM [dbo].[RangeTest] 
							   WHERE ([Condition] = 'Equals')
								 AND (@FromValue = [FromValue])
							 )
						BEGIN
							SET @OK = 0;
							RAISERROR ('FromValue conflicts with existing Equals entry', 1, 1);
						END

					IF EXISTS(SELECT 1 
								FROM [dbo].[RangeTest] 
							   WHERE ([Condition] = 'Between')
								 AND (@FromValue >= [FromValue])
								 AND (@FromValue <= [ToValue])
							 )
						BEGIN
							SET @OK = 0;
							RAISERROR ('FromValue conflicts with existing Between entry', 1, 1);
						END

					IF EXISTS(SELECT 1 
								FROM [dbo].[RangeTest] 
							   WHERE ([Condition] = 'Greater Than')
								 AND (@FromValue > [FromValue])
							 )
						BEGIN
							SET @OK = 0;
							RAISERROR ('FromValue conflicts with existing Greater-Than entry', 1, 1);
						END
				END

			IF (@ToValue IS NOT NULL)
				BEGIN
					IF EXISTS(SELECT 1 
								FROM [dbo].[RangeTest] 
							   WHERE ([Condition] = 'Equals')
								 AND (@ToValue = [FromValue])
							 )
						BEGIN
							SET @OK = 0;
							RAISERROR ('ToValue conflicts with existing Equals entry', 1, 1);
						END

					IF EXISTS(SELECT 1 
								FROM [dbo].[RangeTest] 
							   WHERE ([Condition] = 'Between')
								 AND (@ToValue >= [FromValue])
								 AND (@ToValue <= [ToValue])
							 )
						BEGIN
							SET @OK = 0;
							RAISERROR ('ToValue conflicts with existing Between entry', 1, 1);
						END

					IF EXISTS(SELECT 1 
								FROM [dbo].[RangeTest] 
							   WHERE ([Condition] = 'Greater Than')
								 AND (@ToValue > [FromValue])
							 )
						BEGIN
							SET @OK = 0;
							RAISERROR ('ToValue conflicts with existing Greater-Than entry', 1, 1);
						END
				END

			IF (@OK = 1)
				INSERT INTO [dbo].[RangeTest]
						   ([FromValue]
						   ,[ToValue]
						   ,[Condition])
					 VALUES
						   (@FromValue
						   ,@ToValue
						   ,@Condition)
						END

	CLOSE curTest;
	DEALLOCATE curTest;
END
GO