У меня есть немного отличающаяся перспектива здесь. Хотя ответ @user43968 дает вероятное выравнивание, почему идентификационные данные необходимы для параллелизма, который действительно необходим? Я верю, не потому что ассоциативности самого бинарного оператора достаточно, чтобы позволить нам параллелизировать уменьшать задание.
, Учитывая выражение A op B op C op D
, ассоциативность гарантирует, что ее оценка эквивалентна (A op B) op (C op D)
, такова, что мы можем оценить sub выражения (A op B)
и (C op D)
параллельно и объединить результаты позже, не изменяя конечный результат. Например, с операцией сложения, начальное значение = 10, и L = [1, 2, 3], мы хотим вычислить 10 + 1 + 2 + 3 = 16. Мы должны быть хорошо, чтобы вычислить 10 + 1 = 11 и 2 + 3 = 5 параллельно и сделать 11 + 5 = 16 наконец.
единственная причина, почему Java требует, чтобы начальное значение было идентификационными данными, о которых я могу думать, состоит в том, потому что разработчики языка хотели сделать реализацию простой, и все параллелизировали sub симметричные задания. Иначе они должны были дифференцировать первое sub задание, которое принимает начальное значение, как введено по сравнению с другими sub заданиями, которые не делают. Теперь, они просто должны одинаково распределить начальное значение каждому sub заданию, которое является также "уменьшением" его собственным.
Однако это больше об ограничении реализации, которое не должно появиться пользователям языка IMO. Мое инстинктивное чувство говорит мне, что там должен существовать простая реализация, которая не требует, чтобы начальное значение было идентификационными данными.
Этот вопрос часто возникает, и, к сожалению, наиболее распространенный (и наиболее переносимый) ответ - создать временную таблицу для хранения идентификаторов, которые должны там присутствовать, и сделайте левое соединение. Синтаксис MySQL и SQL Server очень похож. Единственное реальное отличие - синтаксис временных таблиц.
В MySQL:
declare @id int
declare @maxid int
set @id = 1
select @maxid = max(id) from tbl
create temporary table IDSeq
(
id int
)
while @id < @maxid
begin
insert into IDSeq values(@id)
set @id = @id + 1
end
select
s.id
from
idseq s
left join tbl t on
s.id = t.id
where t.id is null
drop table IDSeq
В SQL Server:
declare @id int
declare @maxid int
set @id = 1
select @maxid = max(id) from tbl
create table #IDSeq
(
id int
)
while @id < @maxid --whatever you max is
begin
insert into #IDSeq values(@id)
set @id = @id + 1
end
select
s.id
from
#idseq s
left join tbl t on
s.id = t.id
where t.id is null
drop table #IDSeq
Это единственное решение Oracle. Он не отвечает на весь вопрос, но оставлен здесь для других, которые могут использовать Oracle.
select level id -- generate 1 .. 19
from dual
connect by level <= 19
minus -- remove from that set
select id -- everything that is currently in the
from table -- actual table
Вот запрос для SQL Server:
;WITH Missing (missnum, maxid)
AS
(
SELECT 1 AS missnum, (select max(id) from @TT)
UNION ALL
SELECT missnum + 1, maxid FROM Missing
WHERE missnum < maxid
)
SELECT missnum
FROM Missing
LEFT OUTER JOIN @TT tt on tt.id = Missing.missnum
WHERE tt.id is NULL
OPTION (MAXRECURSION 0);
Надеюсь, это поможет.