#sql #sql-server #tsql
Вопрос:
У меня есть таблица в SQL Server, в которой хранятся ковры. Каждый из них имеет свой собственный идентификатор и диапазон в метрах (от-до) с цветом.
CREATE TABLE rugs ( [code] VARCHAR (10), [from] INT, [to] INT, [color] VARCHAR (10) ); INSERT INTO rugs VALUES ('RUG001', 0, 1, 'Yellow'); INSERT INTO rugs VALUES ('RUG001', 1, 2, 'Red'); INSERT INTO rugs VALUES ('RUG001', 2, 4, 'Blue'); INSERT INTO rugs VALUES ('RUG001', 3, 5, 'Green'); INSERT INTO rugs VALUES ('RUG002', 0, 1, 'Purple'); INSERT INTO rugs VALUES ('RUG002', 1, 2, 'Orange');
В этом примере он перекрывается в строках, соответствующих синему и зеленому цветам для ковра RUG001. RUG002 в порядке.
Как я могу проверить, для одного и того же ковра, есть ли интервалы с перекрытием?
То, что я пробовал (и это не работает)
Select * from RUGS as R1 INNER JOIN RUGS as R2 ON R1.CODE = R2.CODE WHERE R1.[FROM] lt;= R2.[TO] AND R1.[TO] gt;= R2.[FROM]
Комментарии:
1...
WHERE R1.[from] lt; R2.[to] AND R1.[to] gt; R2.[from] and not(R1.[from] = R2.[from] and R1.[to] = R2.[to] and R1.color = R2.color)
Ответ №1:
Трудно быть уверенным с небольшим набором данных, но работает ли для вас следующее? Использование опережения/задержки для проверки того, попадает ли следующий или последний диапазон в текущий диапазон.
with rug as ( select * , Lead([from]) over(partition by code order by [from]) nextfrom, Lag([to]) over(partition by code order by [to]) lastto from rugs ) select code, [from], [to], color from rug where nextfromlt;[to] or lasttogt;[from]
Ответ №2:
Здесь у вас есть два возможных решения.
- Просто перекрытие с левой стороны:
SELECT * FROM RUGS R1 INNER JOIN RUGS R2 ON R1.CODE = R2.CODE WHERE R1.[TO] lt; R2.[TO] AND R2.[FROM] lt; R1.[TO] --Result /* code from to color code from to color RUG001 2 4 Blue RUG001 3 5 Green */
- Все перекрытия:
SELECT * FROM RUGS R1 INNER JOIN RUGS R2 ON R1.CODE = R2.CODE WHERE R1.[FROM] lt; R2.[FROM] AND R2.[TO] lt; R1.[TO] OR (R2.[FROM] lt; R1.[FROM] AND R2.[TO] lt; R1.[TO] AND R1.[FROM] lt; R2.[TO]) OR (R1.[FROM] lt; R2.[FROM] AND R1.[TO] lt; R2.[TO] AND R2.[FROM] lt; R1.[TO]) -- Result /* code from to color code from to color RUG001 2 4 Blue RUG001 3 5 Green RUG001 3 5 Green RUG001 2 4 Blue */