2016-11-29 5 views
0

Требование: сформировать запрос, который выводит данные на основе телефонных номеров в ответ на пользовательские входы, которые являются значениями StartDate, EndDate и Upper Data Threshold.Условие исключения для SQL-запроса MS Access

Эти входные переменные являются границами для запроса. Таким образом, инструкция SELECT была написана ниже.

Единственное предостережение состоит в том, что если номер телефона имеет одну запись, превышающую порог верхних данных, то ВСЕ записи номеров телефонов, связанные с этим нарушением номера телефона, не должны выводиться вне зависимости от других записей того же номера телефона, что и дон 't нарушает порог данных. Ниже приведен пример входного и ожидаемый результат:

User input Start Date: 1/15/2015 
User input End Date: 11/15/2015 
User input Upper Data Threshold in kB: 50 

[Master] Table in Access: 
Invc Date Mobile Nbr  PktDtVol 
--------- ----------  -------- 
1/15/15 647-409-8206 48kB 
2/15/15 647-409-8206 33kB 
3/15/15 647-409-8206 8000kB 
4/15/15 647-409-8206 20kB 
5/15/15 647-409-8206 10kB 
6/15/15 647-409-8206 0kB 
7/15/15 718-500-2311 3kB 
8/15/15 718-500-2311 45kB 
9/15/15 718-500-2311 25kB 
10/15/15 514-300-3311 33kB 
11/15/15 514-300-3311 20kB 

Ожидаемые результаты в [Temp_Table]:

Invc Date Mobile Nbr  PktDtVol Difference in Days 
--------- ----------  -------- ------------------- 
7/15/15 718-500-2311 3kB    304 
8/15/15 718-500-2311 45kB   304 
9/15/15 718-500-2311 25kB   304 
10/15/15 514-300-3311 33kB   304 
11/15/15 514-300-3311 20kB   304 

Мое текущее решение:

PARAMETERS [Start Date] DateTime, [End Date] DateTime, [Upper Bound 
Usage in KB] IEEEDouble; 

SELECT [Master].[Invc Date], [Master].PktDtVol, [Master].[Mobile Nbr], 
DateDiff("d",[Start Date],[End Date]) AS [Difference in days] INTO 
Temp_Table 
FROM [Master] 
WHERE ((([Master].[Invc Date]) >= [Start Date] And 
     ([Master].[Invc Date])<=[End Date]) AND 
     (([Master].PktDtVol)<= [Upper Bound Usage in KB])); 

647-409-8206 запись не ожидается на выходе, так как потребовалось всего 1 запись, чтобы превзойти 50 КБ (будучи третьей записью), тогда ВСЕ записи 647-409-8206 будут соответственно опущены.

Цените любую помощь пожалуйста! Благодаря!

+0

Они выглядят как реальные телефонные номера и поиск в качестве реальных телефонных номеров. Вы действительно хотите поделиться этим с несколькими людьми? – Fionnuala

+0

Они, конечно, поддельные номера, я изменил данные соответственно - но спасибо! – stitch70

+0

У вас также есть некоторые ошибки в дизайне. – Fionnuala

ответ

1

Сначала напишите подзапрос, выбирая все (разные) мобильные номера, для которых строка нарушает порог. Затем выберите из таблицы все строки WHERE [Mobile Nbr] NOT IN (subquery).

+0

Оба ответа помогли! Вот точный оператор SELECT, который я использовал: PARAMETERS [Дата начала] DateTime, [Конечная дата] DateTime, [Использование верхней границы в KB] IEEEDouble; SELECT m. [Invc Date], m.PktDtVol, м. [Mobile Nbr], DateDiff ("d", [Дата начала], [Конечная дата]) AS [Разница в днях] INTO Temp_Table FROM Master AS m WHERE (m. [Invc Date]> = [Дата начала] и m. [Invc Date]) <= [Конечная дата] И м. [Мобильный Nbr] NOT IN (SELECT q. [Mobile Nbr] FROM Master AS q WHERE (q.PktDtVol> = [Использование верхней границы в KB])); – stitch70

+0

В следующий раз, есть ли способ оптимизировать это? Я имею дело с> 100 000 записей, и запрос в настоящее время занимает очень много времени (близок к зависанию). – stitch70

+0

Зависит немного от вашей системы базы данных. Я не склонен работать с ms-доступом (и если переключение является опцией Я бы порекомендовал Postgres, SQL Server или Oracle или SQLite для легковесных приложений), но я мог представить, что MS Access плохо обрабатывает подзапросы. Поэтому вы можете попробовать «LEFT OUTER JOIN» с подзапросом, добавив предложение WHERE, в котором вы гарантируете, что ключ подзапроса «IS NULL». В основном 'SELECT ... FROM table LEFT OUTER JOIN (подзапрос) s ON ... WHERE s. [Mobile Nr] IS NULL'. Это должно гарантировать, что подзапрос оценивается только один раз. –

1

Это довольно грубо, и ваш дизайн нуждается в работе, но он должен дать вам начало.

PARAMETERS [Start Date] DATETIME, [End Date] DATETIME, [Upper Bound Usage in KB] 
IEEEDOUBLE; 

SELECT m.[invc date], 
     m.[mobile nbr], 
     m.[pktdtvol], 
     Datediff("d", [start date], [end date]) AS [Difference in days] 
INTO temp_table 
FROM master AS m 
WHERE m.[invc date] >= [start date] 
     AND m.[invc date] <= [end date] 
     AND m.[mobile nbr] NOT IN 
      (SELECT q.[mobile nbr] 
      FROM master q 
      WHERE q.pktdtvol >= [upper bound usage in kb]) 
+0

К сожалению, это не работает, так как мой набор записей - более 60 000 записей. Я попытался использовать INDEXING, и пока это не сработало. Есть ли другое решение или, возможно, INDEXING используется неправильно? Я создал индекс, используя «CREATE INDEX» – stitch70

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