MySQL - Выбор из списка чисел те, которые не имеют дубликата в идентификационном поле таблицы

NullPointerException s - исключения, возникающие при попытке использовать ссылку, которая указывает на отсутствие местоположения в памяти (null), как если бы она ссылалась на объект. Вызов метода по нулевой ссылке или попытка получить доступ к полю нулевой ссылки вызовет функцию NullPointerException. Они наиболее распространены, но другие способы перечислены на странице NullPointerException javadoc.

Вероятно, самый быстрый пример кода, который я мог бы придумать для иллюстрации NullPointerException, be:

public class Example {

    public static void main(String[] args) {
        Object obj = null;
        obj.hashCode();
    }

}

В первой строке внутри main я явно устанавливаю ссылку Object obj равной null. Это означает, что у меня есть ссылка, но она не указывает на какой-либо объект. После этого я пытаюсь обработать ссылку так, как если бы она указывала на объект, вызывая метод на нем. Это приводит к NullPointerException, потому что нет кода для выполнения в местоположении, на которое указывает ссылка.

(Это техничность, но я думаю, что она упоминает: ссылка, которая указывает на null, равна 't то же, что и указатель C, указывающий на недопустимую ячейку памяти. Нулевой указатель буквально не указывает на в любом месте , который отличается от указаний на местоположение, которое оказывается недопустимым.)

36
задан Christopher Rapcewicz 9 December 2013 в 02:36
поделиться

4 ответа

Это - проблема, которая довольно распространена: генерация отношения на лету, не составляя таблицу. Решения для SQL для этой проблемы являются довольно неловкими. Один пример с помощью полученной таблицы:

SELECT n.id
FROM
  (SELECT 2 AS id 
   UNION SELECT 3 
   UNION SELECT 4 
   UNION SELECT 5 
   UNION SELECT 6 
   UNION SELECT 7) AS n
  LEFT OUTER JOIN foos USING (id)
WHERE foos.id IS NULL;

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

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

CREATE TABLE num (i int);
INSERT INTO num (i) VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9);

SELECT n.id
FROM 
  (SELECT n1.i + n10.i*10 AS id
   FROM num AS n1 CROSS JOIN num AS n10
   WHERE n1.i + n10.i*10 IN (2, 3, 4, 5, 6, 7)) AS n
  LEFT OUTER JOIN foos USING (id)
WHERE foos.id IS NULL;

я показываю внутренние генерирующиеся значения запроса от 0.. 99 даже при том, что это не необходимо для этого случая. Но у Вас могли бы быть значения, больше, чем 10 в Вашем списке. Дело в том, что с одной таблицей num, можно генерировать большие количества, не имея необходимость обращаться к очень длинным цепочкам с одной UNION на значение. Кроме того, можно определить список требуемых значений в одном месте, которое более удобно и читаемо.

34
ответ дан Bill Karwin 27 November 2019 в 05:55
поделиться

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

SELECT bars.* FROM bars WHERE bars.ID NOT IN (SELECT ID FROM foos)

Как другие плакаты я первоначально записал:

SELECT * FROM foos WHERE foos.ID NOT IN (2, 4, 5, 6, 7)

, но тогда я понял, что это производит напротив того, что Вы хотите.

20
ответ дан Alnitak 27 November 2019 в 05:55
поделиться

Alnitak (и Ваш) решение должно работать, и я не могу вещь ни о чем больше, что может работать только на языке SQL.

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

0
ответ дан Sunny Milenov 27 November 2019 в 05:55
поделиться

У меня была аналогичная проблема. У меня был диапазон, в котором автоматически увеличивающийся первичный ключ имел некоторые пропущенные значения, поэтому сначала я выяснил, сколько их было: select count (*) from node where nid> 1962 . {{ 1}} Сравнивая это число с наибольшим значением, я обнаружил, что число отсутствует. Затем я выполнил этот запрос: выберите n2.nid из узла n1, правый узел соединения n2 на n1.nid = (n2.nid - 1), где n1.nid имеет значение null, а n2.nid> 1962 Будет найдено количество пропущенных записей, не следующих подряд. Он не будет показывать последовательные, и я не совсем уверен, как это сделать, кроме изменения предложения ON, чтобы обеспечить большую широту (что значительно увеличило бы таблицу JOIN). В любом случае это дал мне пять результатов из семи отсутствующих, а два других гарантированно были рядом по крайней мере с одним из пяти. Если вам не хватает большего числа, вам, вероятно, понадобится другой способ найти пропавшее.

1
ответ дан 27 November 2019 в 05:55
поделиться
Другие вопросы по тегам:

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