SQL: найдите недостающие идентификаторы в таблице

У меня есть немного отличающаяся перспектива здесь. Хотя ответ @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. Мое инстинктивное чувство говорит мне, что там должен существовать простая реализация, которая не требует, чтобы начальное значение было идентификационными данными.

касательно: http://czheo.github.io/tech/2019/10/24/the-first-argument-of-stream-reduce-does-not-need-to-be-identity-in-java/

51
задан Roee Adler 7 September 2009 в 03:12
поделиться

3 ответа

Этот вопрос часто возникает, и, к сожалению, наиболее распространенный (и наиболее переносимый) ответ - создать временную таблицу для хранения идентификаторов, которые должны там присутствовать, и сделайте левое соединение. Синтаксис 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
30
ответ дан 7 November 2019 в 10:10
поделиться

Это единственное решение 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
4
ответ дан 7 November 2019 в 10:10
поделиться

Вот запрос для 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); 

Надеюсь, это поможет.

21
ответ дан 7 November 2019 в 10:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: