Вопрос

См. следующий оператор SQL:

SELECT datediff("d", MAX(invoice.date), Now) As Date_Diff
      , MAX(invoice.date) AS max_invoice_date
      , customer.number AS customer_number
FROM invoice 
    INNER JOIN customer 
        ON invoice.customer_number = customer.number
GROUP BY customer.number 

Если было добавлено следующее:

HAVING datediff("d", MAX(invoice.date), Now) > 365

будет ли это просто исключать строки с Date_Diff <= 365?

Каков должен быть здесь эффект предложения HAVING?

РЕДАКТИРОВАТЬ:Я не понимаю того, о чем говорят здесь ответы.Копия MDB находится по адресу http://hotfile.com/dl/40641614/2353dfc/test.mdb.html (без макросов и вирусов).VISDATA.EXE используется для выполнения запросов.

РЕДАКТИРОВАТЬ2:Я думаю, что проблема может быть в VISDATA, потому что через DAO я получаю разные результаты.

Это было полезно?

Решение

Как уже указали, да, то это эффект. Для полноты, «имеющие» похоже на «где», но для уже агрегированных (сгруппированных) ценностей (например, max в этом случае или сумма или счетчика или любой другой из других агрегатных функций).

Другие советы

Да, это исключит эти строки.

Да, это то, что это будет делать.

WHERE применяется ко всем отдельным строкам, поэтому WHERE MAX(...) будет соответствовать всем строкам.

HAVING — это то же самое, что WHERE, но внутри текущей группы.Это означает, что вы можете делать такие вещи, как HAVING count(*) > 1, что будет отображать только группы с более чем одним результатом.

Итак, чтобы ответить на ваш вопрос, в него будут включены только те строки, в которых запись в группе с самой высокой (MAX) датой превышает 365.В этом случае вы также выбираете MAX(date), так что да, строки с date_diff <= 365 исключаются.

Однако вы можете выбрать MIN(дата) и увидеть минимальную дату во всех группах, максимальная дата которых превышает 365.В этом случае будут исключены не «строки» с date_diff <= 365, а группы с max(date_diff) <= 365.

Надеюсь, это не слишком запутанно...

Вы можете пробовать неправильные вещи с вашим макс. Увеличивая столбец Invoice.date, вы эффективно ищете самый последний счет, связанный с клиентом. Настолько эффективно, имеющее условие выбирает все эти клиенты, которые имеют нет было Любые Счета в течение последних 365 дней.

Это то, что вы пытаетесь сделать? Или вы на самом деле пытаетесь заставить всех клиентов, у которых есть хотя бы один счет более года назад? Если это так, то вы должны поместить максимум вне функции Dateiff.

Это зависит от того, имеете ли вы строки в таблице или строки в результате. То having Пуск фильтрует результат после группировки, поэтому он будет представлять клиентов, а не счета.

Если вы хотите отфильтровать новые счета, а не клиенты с новыми счетами, вы должны использовать where вместо этого, чтобы вы фильтровали перед группировкой:

select
  datediff("d",
  max(invoice.date), Now) As Date_Diff,
  max(invoice.date) as max_invoice_date,
  customer.number
from
  invoice 
  inner join customer on invoice.customer_number = customer.number
where
  datediff("d", invoice.date, Now) > 365
group by
  customer.number

Я бы не использовал группу по запросу вообще. Используя стандартную струю SQL:

  SELECT Customer.Number
  FROM [SELECT DISTINCT Invoice.Customer_Number
     FROM Invoice
     WHERE (((Invoice.[Date])>Date()-365));]. AS Invoices 
  RIGHT JOIN Customer ON Invoices.Customer_Number = Customer.Number
  WHERE (((Invoices.Customer_Number) Is Null));

Использование режима совместимости SQL92:

  SELECT Customer.Number
  FROM (SELECT DISTINCT Invoice.Customer_Number
     FROM Invoice
     WHERE (((Invoice.[Date])>Date()-365));) AS Invoices 
  RIGHT JOIN Customer ON Invoices.Customer_Number = Customer.Number
  WHERE (((Invoices.Customer_Number) Is Null));

Ключ здесь состоит в том, чтобы получить набор номеров клиента, которые имели счет в прошлом году, а затем выполнив внешнее соединение на этом результате, чтобы вернуть только те, которые не в наборе клиентов со счетами в прошлом году.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top