Почему там, где нет, возвращаются идентификаторы?

#sql #postgresql

Вопрос:

мой вопрос:

 select a.id, a.affiliation 
FROM public.affiliation AS a
WHERE NOT EXISTS (
  SELECT *
  FROM ncbi.affi_known1 AS b 
  WHERE  a.id = b.id
)
limit 5000
 

он возвращается:

ID присоединение
4683763 Отделение психофармакологии, Здание Дороти Ходжкин, Бристольский университет, Уитсон-стрит, Бристоль, BS1 3NY, Великобритания.

как первый ряд.

но

 select * from ncbi.affi_known1 where id = 4683763
 

возвращайте данные с помощью id = 4683763

оба идентификатора имеют тип int8

таблица а

 CREATE TABLE "public"."affiliation" (
  "id" int8 NOT NULL,
  "affiliation" text COLLATE "pg_catalog"."default",
  "tsv_affiliation" tsvector,
  CONSTRAINT "affiliation_pkey" PRIMARY KEY ("id")
)
;
CREATE INDEX "affi_idx_tsv" ON "public"."affiliation" USING gin (
  to_tsvector('english'::regconfig, affiliation) "pg_catalog"."tsvector_ops"
);

CREATE INDEX "tsv_affiliation_idx" ON "public"."affiliation" USING gin (
  "tsv_affiliation" "pg_catalog"."tsvector_ops"
);
 

таблица в

 CREATE TABLE "ncbi"."affi_known1" (
  "id" int8 NOT NULL,
  "affi_raw" text COLLATE "pg_catalog"."default",
  "affi_main" text COLLATE "pg_catalog"."default",
  "affi_known" bool,
  "divide" text COLLATE "pg_catalog"."default",
  "divide_known" bool,
  "sub_divides" text[] COLLATE "pg_catalog"."default",
  "country" text COLLATE "pg_catalog"."default",
  CONSTRAINT "affi_known_pkey" PRIMARY KEY ("id")
)
;
 

Обновить:

после создания индекса по идентификатору все работает хорошо.
удалите индекс, кажется, что-то пошло не так.
итак, почему идентификатор первичного ключа там не работает.

обновление 2:

таблица b создается из таблицы a с использованием:

 query = '''
    select a.id, a.affiliation 
    FROM public.affiliation AS a
    WHERE NOT EXISTS (


     SELECT 1
      FROM ncbi.affi_known AS b 
      WHERE  a.id = b.id
    )
    limit 2000000
    
'''   
data = pd.read_sql(query,conn)

while len(data):
    for i,row in tqdm(data.iterrows()):

        ...


        curser_insert.execute(
            'insert into ncbi.affi_known(id,affi_raw, affi_main ,affi_known,divide,country) values ( %s,  %s, %s,%s,%s,%s) ',
            [affi_id,affi_raw, affi_main, affi_known,devide,country]
        )
        conn2.commit()
        

    conn2.commit()
    conn.commit()
    data = pd.read_sql(query, conn)
 

и код выходит неправильно.

Комментарии:

1. Покажите выполняемый тестовый случай с поведением, о котором вы сообщили. Отрегулируйте эту скрипку по мере необходимости: dbfiddle.uk/…

2. Что такое тип данных id ?

Ответ №1:

Ваше понимание того, как EXISTS это работает, может быть неправильным. Ваш текущий запрос exists указывает, что идентификатор 4683763 существует в affiliation таблице, а не в affi_known1 таблице. Таким образом, следующий запрос должен возвращать единственную запись:

 SELECT a.id, a.affiliation 
FROM public.affiliation a
WHERE a.id = 4683763;
 

Комментарии:

1. Я хочу, чтобы запись ge была в таблице a, а не в таблице b.

2. affi_known1 генерируются на основе принадлежности к таблице

Ответ №2:

Я предполагаю, что требование состоит в том, чтобы извлекать строки только тогда, когда идентификатор отсутствует во второй таблице, поэтому вы можете попробовать это

 
select a.id, a.affiliation 
FROM public.affiliation AS a
WHERE a.id NOT IN (
  SELECT id
  FROM ncbi.affi_known1 
)

 

Ответ №3:

Если id бы это было целое число, ваш запрос делал бы то, что вы хотите.

Если id это строка, у вас могут возникнуть проблемы с «двойниками». Очень трудно сказать , в чем проблема-в них могут быть пробелы id , скрытые символы или что-то еще. И это может быть в любой таблице.

Предполагая, что идентификаторы выглядят как числа, вы можете отфильтровать «плохие» идентификаторы с помощью регулярных выражений:

 select id
from ncbi.affi_known1
where not id ~ '^[0-9]*


Комментарии:

1. оба идентификатора являются int8

;

Комментарии:

1. оба идентификатора являются int8