User 13204940 Ответов: 2

Если в таблице существует несколько записей SQL


Привет,

Я пытаюсь вывести результаты в следующем формате;

number exists
123456 1
345633 0
243234 1
865445 1


где "существует" равно 1 или 0 в зависимости от того, существует ли "число" в таблице X.

Я пробовал все виды вещей, но это всегда заканчивается тем, что показывает только те числа, которые существуют рядом с 1, но не показывает те, которые не существуют рядом с 0.

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

ОБНОВЛЕНИЕ:

Теперь у меня есть:

CREATE TEMPORARY TABLE numbers
(number int(11));

insert into numbers (number) values
(1),(2),(3);

SELECT n.number
COALESCE((SELECT TOP 1
        1
where n.number in ('1','2','3','4')), 0) AS 'exists'
FROM numbers n

но теперь есть еще одна синтаксическая ошибка,
Error in query (1064): Syntax error near '((SELECT TOP 1 1 where n.number in ('1','2','3','4')), 0) AS 'exists' ' at line 2


Что я уже пробовал:

ВЫБЕРИТЕ 1 ГДЕ СУЩЕСТВУЕТ
ВНУТРЕННЕЕ СОЕДИНЕНИЕ
СОЮЗ

F-ES Sitecore

Не знаю, почему вы думаете, что кто-то может дать вам рабочий запрос, не зная схемы базы данных или некоторых образцов данных. Несмотря на это, вы, вероятно, хотите "соединить слева" две таблицы вместе и сделать какой-то "случай, когда", который возвращает 1, является полем в таблице, которую вы оставили присоединенной, "не нулевым" и 0, если оно "равно нулю".

[no name]

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

F-ES Sitecore

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

[no name]

Я точно знаю, какая часть является примером данных, это очевидно. Не принимайте меня за идиота.

F-ES Sitecore

Так почему же вы ответили жалобой на настройку выборочных данных, а не посмотрели на суть запроса, поняв его и применив к своим собственным данным?

[no name]

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

F-ES Sitecore

Да, это так, тот бит синтаксиса, который, как вы сказали, не работает, не нужен для вашего решения, это просто настройка тестовых данных.

[no name]

Без создания постоянных таблиц именно так я и собираюсь это сделать, но это не работает, и это не имеет никакого отношения к моей реализации.

2 Ответов

Рейтинг:
1

Bryian Tan

Вы можете попробовать что-то вроде

DECLARE @tableY TABLE (Number INT)

DECLARE @tableX TABLE (Number INT)

INSERT INTO @tableY
	SELECT 123456  UNION
	SELECT 345633   UNION
	SELECT 243234   UNION
	SELECT 865445   

INSERT INTO @tableX
	SELECT 345633   UNION
	SELECT 243234   UNION
	SELECT 865445   

SELECT Y.Number, 
CASE 
	WHEN ISNULL(x.Number,'') = '' THEN 0
	ELSE 1
END 'Exists'
FROM @tableY y
LEFT JOIN @tableX x
ON y.Number = x.Number


Выход:
Number	Exists
123456	0
243234	1
345633	1
865445	1


[no name]

Я получаю

Ошибка в запросе (1064): ошибка синтаксиса около 'объявить @таблица табли (количество ИНТ) объявляют @таблица tableX (число типа int) ИНСЭ' в строке 1

Bryian Tan

вы используете Microsoft SQL server? или база данных Oracle?

[no name]

Я обновил вопрос с помощью своего текущего кода

Maciej Los

5ed!

Jörgen Andersson

Вам, наверное, стоит обменяться WHEN ISNULL(x.Number,'') = '' THEN 0 для WHEN x.Number IS NULL THEN 0
Он сохраняет одну операцию и приведение и, вероятно, более корректен в другом случае, когда обе таблицы фактически содержат ''

Рейтинг:
1

Wendelius

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

Что касается самого запроса, то это можно сделать несколькими способами. Лично я пожалуй предпочел бы следующий формат

SELECT a.TestNumber,
       COALESCE( (SELECT TOP 1
               1
        FROM DataTable b
        WHERE b.Number = a.TestNumber), 0) AS Exists
FROM NumberToTestTable a

Приведенный выше запрос должен предотвратить умножение строк в случае, если число Существует несколько раз в таблице данных. Также TOP 1 структура должна закончить расследование, как только будет найдено совпадение.

С точки зрения производительности было бы крайне важно индексировать Number колонка в центре DataTable для того, чтобы эффективно сканировать данные.


[no name]

Они придут изнутри('1','2','3') и т. д.

Wendelius

И вы хотите иметь строку в результирующем наборе, если число не найдено? Если это так, то вам нужна строка, которая будет указана в результате, следовательно, вам нужна таблица (или функция), содержащая числа для тестирования.

[no name]

Я обновил вопрос с помощью своего текущего кода

Wendelius

В вашем обновленном коде вы забыли предложение FROM из коррелированного подзапроса


...
FROM DataTable b
...


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

Maciej Los

5ed!

Wendelius

Спасибо!