2015-08-17 5 views
1
SELECT * 
FROM Table1 D1 (nolock) 
WHERE 1 = 1 
    AND NOT EXISTS (SELECT TOP 1 * 
FROM Table2 D2 (nolock) 
WHERE d1.Account = d2.Account 
    AND d2.Amount BETWEEN (d1.Amount - 5) AND (d1.Amount + 5) 
    AND Datediff(DD, d1.SALEDATE, d2.SALEDATE) BETWEEN 0 AND 60) 

Я удалил много функций, которые не имеют отношения к вопросу.Value2 МЕЖДУ (Value1 - 5) AND (Value1 + 5)

По существу, я хочу, чтобы он находил записи, когда определенные критерии выполнялись в первой части (я использую 1 = 1 для простоты здесь), а затем исключаю все, что имело продажу за последние 60 дней за сумму -/+ $ 5 на том же счете.

По какой-то причине он просто возвращает 0 записей каждый раз, но при осмотре таблицы базы данных вручную это неверно. Я использую Transact SQL.

+0

Возможно ли, что у вас есть разница в обратном направлении? (т. е. он должен быть «между -60 и 0' - или наоборот' d1' и 'd2') –

+0

Не имеет значения для результатов. Таким образом, я использовал Datediff сотни раз и никаких проблем. Это первый раз, когда я использую выражение с d2.Amount BETWEEN (d1.Amount - 5) AND (d1.Amount + 5). –

+0

Нет проблем. Был только удар в темноте. Можете ли вы дать нам пример набора данных для работы? –

ответ

1

Хорошо, решил ... так просто ... Я забыл исключить результаты из D1. Итак, теперь у него есть d2.indexkey <> инструкция d1.indexkey, и все это работает. Lol

+0

Определенно не заметил бы это из вашего приведенного примера, особенно если это было собственно самосоединение. (У вас есть две * разные * таблицы в вопросе). Рад, что вы это решили. –

+0

Да, извините.Это моя первая публикация здесь, и я пытался скрыть конфиденциальную работу вещей. Трудно задавать вопросы людям при работе с конфиденциальными процессами и данными :( –

0

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

SELECT * into #temp 
FROM Table1 D1 


select * from #temp t1 
WHERE t1.id not in(
    SELECT t2.id 
     FROM #temp t2 
    WHERE t1.Account = t2.Account 
     AND t2.Amount BETWEEN (t1.Amount - 5) AND (t1.Amount + 5) 
     AND Datediff(DD, t1.SALEDATE, t2.SALEDATE) BETWEEN 0 AND 60) 

Однако это просто чередует ваш запрос.

Преимущества временных таблиц

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

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

  • Таблицы Temp, в то время как они имеют пространство, назначенное им в базе данных tempDB, обычно будут доступны только из памяти, если только сервер не находится под давлением памяти или объем данных в таблице невелик.

+0

Использует ли таблица temp/Physical table какую-либо разницу в производительности? можете ли вы объяснить или дать некоторую ссылку? – Biswabid

+0

Добавлены некоторые преимущества, почему мы предпочитаем временную таблицу. –

+0

... и встроенные таблицы будут также доступны также из памяти. Внутренние таблицы также будут повторно использоваться, если они попадут в память. То, что вы предлагаете, заключается в том, что загрузка столбца _every_ в временную таблицу будет быстрее, чем использование «EXISTS» (которое достаточно интеллектуально, чтобы получить доступ только к минимальному количеству данных, требуемых на страницах). –

Смежные вопросы