SQL - Как вернуть логическое значение, если значения существуют в таблице - PullRequest
2 голосов
/ 24 мая 2019

У меня есть куча значений (посылок), которые мне нужно проверить в базе данных, чтобы убедиться, что все они уже существуют. Иногда есть сотни таких посылок. Я хочу вернуть в основном значение true или false, чтобы я мог узнать, какое из них не существует, и обратиться к этой конкретной посылке. Аспект даты - мне нужно фильтровать всегда по предыдущему году. Я довольно зеленый с SQL, поэтому я ценю помощь.

Я пробовал это:

SELECT *,
CASE WHEN EXISTS (SELECT * FROM Property WHERE taxyear = YEAR(GETDATE()) - 1 and (parcel in 
('1719309002000',
 '1024247013000',
 '1024247008000',
 '1024247001000'))
 THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT) END AS ExistsStatus
 FROM Property

и

SELECT Parcel, Powner, taxyear, 
CASE WHEN taxyear = YEAR(GETDATE()) - 1 and (parcel in 
('1719309002000',
 '1024247013000',
 '1024247008000',
 '1024247001000'
)) 
THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT) END AS result_field
FROM Property;

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

Ответы [ 4 ]

1 голос
/ 24 мая 2019

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

Делая это, вы начинаете с таблицы, которая содержит все номера участков, которые вы ищете, а затем СЛЕДУЕТ ПРИСОЕДИНИТЬСЯ к реальным даннымчтобы вы не потеряли ни одной строки в соединении.Наконец, оператор CASE проверяет, удалось ли соединению соединить существующую строку.

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

SELECT InputTable.parcel, (CASE WHEN Property.parcel IS NOT NULL THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT) END) AS ExistsStatus
FROM (
  SELECT '1719309002000' AS parcel UNION
  SELECT '1024247013000' UNION
  SELECT '1024247008000' UNION
  SELECT '1024247001000'
) AS InputTable
LEFT JOIN Property ON Property.parcel = InputTable.parcel AND Property.taxyear = YEAR(GETDATE()) - 1
1 голос
/ 24 мая 2019

Я бы порекомендовал exists с таблицей значений.Это предотвратит дублирование в наборе результатов:

SELECT v.parcel,
       (CASE WHEN EXISTS (SELECT 1
                          FROM Property p
                          WHERE p.taxyear = YEAR(GETDATE()) - 1 AND
                                p.parcel = v.parcel
                         ) 
             THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)
        END) AS ExistsStatus
FROM (VALUES ('1719309002000'),
             ('1024247013000'),
             ('1024247008000'),
             ('1024247001000')
     ) v(parcel)
0 голосов
/ 24 мая 2019

Вы можете достичь этого, используя UNION операцию.Как следующий запрос:

SELECT Parcel, MAX(result_field) AS result_field
FROM
(
  SELECT 
    Parcel,
    1 AS result_field -- exists in Property table, so value is 1
  FROM Property
  WHERE TaxYear = YEAR(GETDATE() -1)

  UNION

  -- create a temporary table with your given Parcels
  SELECT 
    Parcel,
    0 AS result_field -- doesn't exist in Property table, So it's 0
  FROM (
   VALUES
     ('1719309002000'),
     ('1024247013000'),
     ('1024247008000'),
     ('1024247001000')
   ) AS T (Parcel)

) AS ResultTable
GROUP By Parcel

Вот рабочая dbfiddle .

Надеюсь, это поможет.Спасибо!

0 голосов
/ 24 мая 2019

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

Create Table #MyParcels( ParcelNumber bigint);
INSERT #MyParcles VALUES ('1234567890'), ('2345678901'), ....

SELECT ParcelNumber, CASE WHEN parcel is null THEN 0 ELSE 1 END as [Exists] FROM #MyParcels LEFT OUTER JOIN Property ON ParcelNumber = parcel

Это вернет 1 строку для каждой записи в #MyParcels с 0/1, указывающим, существует ли он в свойстве.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...