#sql #sql-server #sql-server-2005
#sql #sql-сервер #sql-server-2005
Вопрос:
У меня есть таблица, подобная приведенной ниже
CREATE TABLE [dbo].[LINE](
[ID] [nvarchar](50) NOT NULL,
[LINE_NUM] [int] NOT NULL
) ON [PRIMARY]
insert into LINE select '01201301090100600004', '1'
insert into LINE select '01201301090100600004', '2'
insert into LINE select '01201301090100600004', '3'
insert into LINE select '01201301090100600004', '4'
insert into LINE select '01201301090100600005', '1'
insert into LINE select '01201301090100600005', '4'
insert into LINE select '01201301090100600005', '5'
insert into LINE select '01201301100045200002', '1'
insert into LINE select '01201301100045200002', '2'
insert into LINE select '01201301100045200002', '3'
insert into LINE select '01201301100081300008', '1'
insert into LINE select '01201301100081300008', '3'
я хочу выбрать записи, в которых столбец LINE_NUM является непрерывным. Оно должно начинаться с 1. Поэтому я хочу выбрать только следующее
'01201301090100600004', '1'
'01201301090100600004', '2'
'01201301090100600004', '3'
'01201301090100600004', '4'
'01201301100045200002', '1'
'01201301100045200002', '2'
'01201301100045200002', '3'
Как мне это сделать?
Отредактированный вопрос:
Я ищу, чтобы получить различные идентификаторы, где число СТРОК начинается с 1, а также, если для идентификатора имеется более одного числа СТРОК, затем проверьте, являются ли они последовательными, и извлеките эти идентификаторы?
я использовал это, чтобы получить его
SELECT id,
m.line_num,
m.new_line_num
FROM (SELECT t.line_num AS old_line_num,
t.*
FROM (SELECT t.*,
Row_number()
OVER (
partition BY clm_id
ORDER BY line_num ) AS new_line_num
FROM line t) t) m
WHERE m.line_num <> m.new_line_num
Комментарии:
1. @Neeku ВЫБЕРИТЕ ID , m.LINE_NUM ,m.new_line_num ИЗ (ВЫБЕРИТЕ t.LINE_NUM КАК old_line_num , т.* ИЗ (ВЫБЕРИТЕ t.* , row_number() ПОВЕРХ (РАЗДЕЛЕНИЕ ПО ПОРЯДКУ CLM_ID ПО LINE_NUM) КАК new_line_num ИЗ СТРОКИ t ) t ) m ГДЕ m.LINE_NUM <> m .new_line_num
Ответ №1:
Вы можете сделать это с row_number()
помощью . Если значения являются последовательными (более точный термин, чем «непрерывный»), то разница будет постоянной:
select id, line_num
from (select t.*,
min(diff) over (partition by id) as mindiff,
max(diff) over (partition by id) as maxdiff
from (select t.*,
(line_num - row_number() over (partition by id order by line_num)) as diff
from table t
) t
) t
where mindiff = maxdiff and mindiff = 1;
Если вы просто хотите найти id
s, в которых нет пробелов, вам даже не нужны оконные функции:
select t.id
from table t
group by t.id
having (max(line_num) - min(line_num) 1 = count(distinct line_num));
Комментарии:
1. Я все еще получаю идентификаторы с номерами разорванных строк
2. @user176047 . , , Вы можете отредактировать свой вопрос и привести несколько примеров? Или, что еще лучше, настройте SQL-скрипку?
3. @user176047 . , , Запрос в вашем пересмотренном вопросе не является запросом в моем ответе.
Ответ №2:
Вы могли бы использовать ROW_NUMBER() OVER (ORDER BY ID)
для упорядочения по столбцу ID. Затем используйте это, чтобы проверить, имеет ли следующая строка Line_Num 1
:
WITH CTE AS
(
SELECT IdNum = ROW_NUMBER() OVER (ORDER BY ID), *
FROM dbo.LINE
)
SELECT ID,LINE_NUM
FROM CTE
WHERE (SELECT LINE_NUM FROM CTE c2
WHERE c2.IdNum = CTE.IdNum 1) = LINE_NUM 1
Комментарии:
1. для запуска требуется много времени, но все равно выбираются идентификаторы с непоследовательным LINE_NUM
Ответ №3:
Может быть, мы также можем сделать это
declare @Line TABLE (
[ID] [nvarchar](50) NOT NULL,
[Line_NUM] [int] NOT NULL
)
insert into @Line select '01201301090100600004', '1'
insert into @Line select '01201301090100600004', '2'
insert into @Line select '01201301090100600004', '3'
insert into @Line select '01201301090100600004', '4'
insert into @Line select '01201301090100600005', '1'
insert into @Line select '01201301090100600005', '4'
insert into @Line select '01201301090100600005', '5'
insert into @Line select '01201301100045200002', '1'
insert into @Line select '01201301100045200002', '2'
insert into @Line select '01201301100045200002', '3'
insert into @Line select '01201301100081300008', '1'
insert into @Line select '01201301100081300008', '3'
;WITH CTE AS
(
select ID,Line_NUM,RN=ROW_NUMBER()OVER(PARTITION by ID ORDER BY Line_NUM ) from @Line
),CTE2 AS
(
Select distinct
ID,Line_NUM,RR = ROW_NUMBER()OVER(PARTITION by ID ORDER BY Line_NUM )
from CTE
WHERE Line_NUM = RN
GROUP BY ID,Line_NUM,RN
)
,CTE3 AS
(
Select C.id,C.Line_NUM,RANK() OVER(Order By c.id) as t_index FROM CTE2 C
GROUP BY C.ID,C.RR,c.Line_NUM
)
Select ID,Line_Num from
(Select DISTINCT cc.ID,CC.Line_NUM,COUNT(CC.t_index)OVER (Partition by cc.ID)RS from CTE3 CC)Z
WHERE RS > 1