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

Вы можете использовать lookaround.

/^abc(?!.*abc).*123.*(?<!xyz.*)xyz$/g

(я его не тестировал.)

308
задан z-boss 30 July 2013 в 14:51
поделиться

9 ответов

SELECT t1.name
FROM table1 t1
LEFT JOIN table2 t2 ON t2.name = t1.name
WHERE t2.name IS NULL

Q: Что здесь происходит?

A: По идее мы выбираем все строки из table1 и для каждой строки мы пытаемся найти строку в table2 с тем же значением для столбца name. Если такой строки нет, мы просто оставим часть table2 нашего результата пустым для этой строки. Затем мы ограничиваем наш выбор, выбирая только те строки в результате, где совпадающая строка не существует. Наконец, мы игнорируем все поля из нашего результата, кроме столбца name (тот, который мы уверены, что существует, из table1).

Хотя это может быть не самый эффективный метод во всех случаях он должен работать в основном каждый движок базы данных, когда-либо пытающийся реализовать ANSI 92 SQL

577
ответ дан Kris 18 August 2018 в 19:17
поделиться
  • 1
    @ z-boss: он также наименее эффективен на SQL Server: explainextended.com/2009/09/15/… – OMG Ponies 21 April 2010 в 21:32
  • 2
    Спасибо, хорошо работает с большими наборами данных – sirus 2 February 2015 в 12:29
  • 3
    @NimbleFungus: Я добавил некоторое объяснение, это вам поможет? – Kris 29 September 2016 в 08:55
  • 4
    @BunkerBoy: левое соединение позволяет строкам справа не существовать, не влияя на включение строк слева. Для внутреннего соединения требуются строки слева и справа для присутствия. Что я здесь делаю, применяю некоторую логику, чтобы в принципе получить обратный выбор внутреннего соединения. – Kris 25 January 2017 в 14:56
  • 5
    Следует отметить, что эти решения (принятые и проголосованные) являются единственными, я думаю, они могут быть отредактированы для сценария, в котором задействовано более одного поля. В частности, я возвращаю поле, поле 2, поле 3 из таблицы, где комбинация поля полевого объявления2 не находится во второй таблице. Помимо изменения соединения в этом ответе, я не вижу способа сделать это с некоторыми другими «более эффективными ответами». утверждал ниже – TMWP 2 May 2018 в 19:18

Я собираюсь репонировать (так как я еще не достаточно крут, чтобы комментировать) в правильном ответе .... на тот случай, если кто-либо еще подумал, что ему нужно лучше объяснить.

SELECT temp_table_1.name
FROM original_table_1 temp_table_1
LEFT JOIN original_table_2 temp_table_2 ON temp_table_2.name = temp_table_1.name
WHERE temp_table_2.name IS NULL

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

Суть в том, что вы используете неправильные имена переменных, которые оставляют вопросы. Мои переменные должны иметь больше смысла. И кто-то должен объяснить, почему нам нужна запятая или нет запятой.

-1
ответ дан Adrian Roth 18 August 2018 в 19:17
поделиться

Следите за ловушками. Если поле Name в Table1 содержит Nulls, вы попадаете в сюрпризы. Лучше:

SELECT name
FROM table2
WHERE name NOT IN
    (SELECT ISNULL(name ,'')
     FROM table1)
13
ответ дан dekkard 18 August 2018 в 19:17
поделиться
  • 1
    COALESCE & gt; ISNULL (ISNULL - это бесполезное дополнение T-SQL к языку, который не делает ничего нового или лучше, чем COALESCE) – Kris 16 June 2017 в 11:53

Вот что сработало лучше для меня.

SELECT *
FROM @T1
EXCEPT
SELECT a.*
FROM @T1 a
JOIN @T2 b ON a.ID = b.ID

Это было более чем в два раза быстрее, чем любой другой метод, который я пытался.

8
ответ дан Diligent Key Presser 18 August 2018 в 19:17
поделиться
  • 1
    Спасибо, эта работа хорошо с большим количеством данных тоже! Но я просто задаюсь вопросом о «Исключении». – PatsonLeaner 24 June 2018 в 12:35

Вы можете использовать EXCEPT в mssql или MINUS в oracle, они идентичны в соответствии с:

http://blog.sqlauthority.com/2008/08/07/ SQL-сервер, за исключением-п-в-SQL-Server-это автомодельный к минусу-пункт-в-оракула /

8
ответ дан Izzy 18 August 2018 в 19:17
поделиться

У меня нет достаточного количества очков для голосования по 2-му ответу. Но я должен не согласиться с комментариями на верхний ответ. Второй ответ:

SELECT name
FROM table2
WHERE name NOT IN
    (SELECT name 
     FROM table1)

На практике FAR эффективнее. Я не знаю, почему, но я запускаю его с записями 800k +, и разница огромна с преимуществом, предоставленным второму ответу, опубликованному выше. Только мои $ 0,02

55
ответ дан Mike K 18 August 2018 в 19:17
поделиться
  • 1
    В запросе NOT IN подзапрос выполняется только один раз, в запросе EXISTS выполняется подзапрос для каждой строки – Carrick 25 February 2014 в 18:49
  • 2
    вы удивительны :) таким образом я конвертирую свой запрос на 25 секунд, используя левое соединение, всего лишь 0,1 с – Bassem Shahin 19 August 2017 в 22:33
  • 3
    ответы не в каком-либо конкретном порядке, поэтому второй ответ не означает, что вы думали, что это значит. – feeling unwelcome 17 July 2018 в 16:14

Это работает для меня

SELECT * 
FROM [dbo].[table1] t1
LEFT JOIN [dbo].[table2] t2 ON t1.[t1_ID] = t2.[t2_ID]
WHERE t2.[t2_ID] IS NULL
6
ответ дан OhBeWise 18 August 2018 в 19:17
поделиться

Вы можете либо сделать

SELECT name
FROM table2
WHERE name NOT IN
    (SELECT name 
     FROM table1)

, либо

SELECT name 
FROM table2 
WHERE NOT EXISTS 
    (SELECT * 
     FROM table1 
     WHERE table1.name = table2.name)

См. этот вопрос для трех методов для выполнения этого

175
ответ дан txemsukr 18 August 2018 в 19:17
поделиться
  • 1
    & Quot; не в & quot; Синтаксис также работает в SQLite. – jftuga 10 January 2014 в 16:33
  • 2
    Это невероятно медленно с большими объемами данных. – Lightbulb1 2 September 2014 в 17:29
  • 3
    Да, действительно, это очень медленно – sirus 2 February 2015 в 12:29
  • 4
    Не должно быть «из таблицы 1». в подзапросе запроса не существует. – Hound 28 July 2017 в 17:21

Это чистая теория множеств, которую вы можете достичь с помощью операции minus.

select id, name from table1
minus
select id, name from table2
32
ответ дан zkanoca 18 August 2018 в 19:17
поделиться
  • 1
    Считаете ли вы, что это намного эффективнее, чем левое соединение? – uhs 21 August 2014 в 18:15
  • 2
    Должен быть. Команда «минус» предназначена для этой конкретной ситуации. Конечно, единственный способ судить по какому-либо конкретному набору данных - это попробовать в обоих направлениях и посмотреть, что работает быстрее. – Winter 5 September 2014 в 03:45
  • 3
    В T-SQL оператор набора является "except". Это очень удобно для меня и не вызвало никакого замедления. – user 19 April 2016 в 18:49
  • 4
    В SQLite «минус» оператор также «исключает». – lifjoy 25 July 2016 в 23:34
Другие вопросы по тегам:

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