Создайте строки данных в таблице, которые не имеют определенного значения столбца

У меня есть таблица, в которой отсутствует информация, которую необходимо вставить с очень конкретными условиями. Однако я не уверен, как действовать дальше.

У меня есть одна таблица, содержащая общее представление информации. Использование проектов в качестве примера

Идентификатор проекта Название проекта 1 Проект А 2 Проект Б 3 Проект С 4 Проект Д

У меня есть еще одна таблица, содержащая часть информации из первой таблицы, в которой показаны статусы и сроки этих проектов.

ProjectStatusID Идентификатор проекта Статус проекта Дата 1 1 Началось 10.02.2020 2 1 В тестировании 06.05.2021 3 1 Законченный 01.07.2021 4 2 В тестировании 30.01.2019 5 2 Законченный 18.03.2020 6 4 Началось 22.10.2016 7 4 Законченный 18.03.2020

Как вы можете видеть из второй таблицы, нет записи о том, когда проект B «начался», а для проекта C вообще нет записей.

Я хочу добавить записи для проектов, у которых нет статуса «начато» с произвольной датой: 01.01.2000. Таким образом, новая вторая таблица будет выглядеть так:

ProjectStatusID Идентификатор проекта Статус проекта Дата 1 1 Началось 10.02.2020 2 1 В тестировании 06.05.2021 3 1 Законченный 01.07.2021 4 2 В тестировании 30.01.2019 5 2 Законченный 18.03.2020 6 4 Началось 22.10.2016 7 4 Законченный 18.03.2020 8 2 Началось 01.01.2000 9 3 Началось 01.01.2000

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

SELECT t.ProjectID FROM t1 t
INNER JOIN t2 tt ON t.ProjectID = tt.ProjectID
WHERE pp.ProjectStatus != 'Started'

Затем я попробовал пойти в другом направлении и нашел все проекты, имеющие желаемый статус, и мне это удалось.

SELECT ProjectStatusID, ProjectID, ProjectStatus FROM t2
WHERE ProjectStatus NOT IN (SELECT ProjectStaus FROM t2
WHERE ProjectStatus != 'Started')

Однако я не уверен, как использовать этот столбец результатов в другом скрипте. Очевидно, я мог бы создать длинную строку, используя предложение Where и скопировав и вставив все значения ProjectID, но это явно неэффективно, особенно если проектов было намного больше, чем те, которые я привел в примере выше.

Почему бы не создать представление, в котором вы создадите фальшивую строку?

siggemannen 30.08.2024 23:06

Пожалуйста, покажите нам свою самую многообещающую попытку. А для более быстрых ответов предоставьте DDL+DML, который создает образцы данных - потому что мне, например, не нравится вводить все это.

Dale K 30.08.2024 23:55

@siggemannen Я хочу обновить существующую таблицу, а не создавать представление.

Andrew C 31.08.2024 00:11

Хорошо, не уверен, что так оно и есть, но вам стоит проверить EXISTS, что-то вроде: SELECT ProjectID from Projects t WHERE NOT EXISTS (select 1 FROM ProjectStatus ps WHERE ps.ProjectID = t.ProjectID AND ps.Status = 'Started')

siggemannen 31.08.2024 00:18
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
2
4
87
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Я думаю, вы просто хотите NOT EXISTS проверить, у каких проектов отсутствует статус «Начато».

insert into ProjectStatus (ProjectId, ProjectStatus, [Date])
select ProjectId, 'Started', '1/1/2000'
from Project p
where not exists (
  select 1
  from ProjectStatus ps
  where ps.ProjectId = p.ProjectId
  and ps.ProjectStatus = 'Started'
);

И если вы хотите добавить статус «Начато» только к проектам, у которых был записан хотя бы один статус, но нет статуса «Начато» (а это не то, что вы просили), вы можете просто проверить отсутствие отсутствующих ProjectStatus с использованием GROUP BY и HAVING, например.

select ProjectId, 'Started', '1/1/2000'
from ProjectStatus
group by ProjectId
having sum(case when ProjectStatus = 'Started' then 1 else 0 end) = 0;

DBFiddle

В будущем я рекомендую добавить DBFiddle, как показано выше, чтобы людям было легче вам помогать.

Dale K 31.08.2024 00:31

Спасибо! Этот ответ помог решить мою проблему. Извините, что не предоставил больше информации. Я не пишу много вопросов на этом сайте и не взаимодействовал с такими вещами, как DBFiddle.

Andrew C 03.09.2024 16:11

Этот ответ хорошо объясняет, как вставить только недостающие строки, для этого я бы использовал точно такую ​​же команду вставки.

Просто чтобы пойти еще дальше: в вашем случае использования весьма вероятно, что вы никогда не захотите, чтобы один и тот же проект имел один и тот же статус несколько раз. Разве что проект можно «перезапустить» и закончить заново. Если да, забудьте этот ответ.

В противном случае, если проект всегда должен начинаться один раз, один раз тестироваться и один раз завершаться, это хороший вариант использования для создания такого уникального индекса:

CREATE UNIQUE INDEX UNQ_Project_Status ON ProjectStatus (ProjectId, ProjectStatus)
  WITH (IGNORE_DUP_KEY = ON); -- this WITH clause is optional

Это гарантирует, что один и тот же проект не может быть запущен/тестирован/завершен несколько раз.

Обратите внимание на необязательную часть WITH (IGNORE_DUP_KEY = ON).

Если вы запускаете команды вставки и вас не волнует, какие строки будут нарушать указанный выше индекс, то это хороший вариант использования этого предложения WITH (хотя можно утверждать, что «чище» исключать дубликаты, а не позволять ограничению или индексу перехватывать их).

В этом случае можно просто выполнить команду вставки без необходимости прописывать условие, какой проект уже запущен:

INSERT INTO ProjectStatus (ProjectId, ProjectStatus, [Date])
  SELECT ProjectId, 'Started', '1/1/2000' FROM Project p;

Недостающие строки будут вставлены, остальные — нет. Вам сообщат, что дубликаты были проигнорированы:

Дубликат ключа был проигнорирован. затронуты 2 строки

Если вам не нужна эта «внутренняя проверка», а вы хотите справиться с ней самостоятельно и узнать, какие команды вставки не работают, вы можете пропустить предложение WITH в определении индекса, но все равно создать индекс.

Затем вы вернетесь к команде вставки с помощью NOT EXISTS, чтобы исключить дубликаты. И вы по-прежнему будете уверены, что никогда не вставите дубликаты по ошибке благодаря индексу.

Если вы когда-нибудь забудете проверить возможные дубликаты в любой команде вставки, вы получите обычное сообщение об ошибке о том, что индекс нарушен.

Посмотрите этот образец скрипки

Прочтите документацию об этом и других параметрах индекса.

Другие вопросы по теме