SQL: предложение HAVING - PullRequest
       6

SQL: предложение HAVING

3 голосов
/ 30 апреля 2010

См. Следующую инструкцию 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? </p>

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

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

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

Ответы [ 7 ]

5 голосов
/ 30 апреля 2010

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

1 голос
/ 30 апреля 2010

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

0 голосов
/ 02 мая 2010

Я бы вообще не использовал запрос GROUP BY. Использование стандартного Jet 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));

Ключом здесь является получение набора номеров клиентов, у которых был счет-фактура в прошлом году, а затем выполнение ВНЕШНЕГО СОЕДИНЕНИЯ с этим набором результатов для возврата только тех, кто не входит в набор клиентов со счетами в в прошлом году.

0 голосов
/ 01 мая 2010

Это зависит от того, имеете ли вы в виду строки в таблице или строки в результате. Предложение 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
0 голосов
/ 01 мая 2010

Возможно, вы пытаетесь сделать что-то не то с вашим МАКС. MAXing столбец invoice.date позволяет эффективно искать самый последний счет, связанный с клиентом. Таким образом, условие HAVING выбирает всех клиентов, у которых не было любых счетов за последние 365 дней.

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

0 голосов
/ 30 апреля 2010

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

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

Таким образом, чтобы ответить на ваш вопрос, он будет включать только те строки, где запись в группе, котораяимеет максимальную (МАКС.) дату, превышающую 365. В этом случае вы также выбираете МАКС. (дата), поэтому да, она исключает строки с date_diff <= 365. </p>

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

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

0 голосов
/ 30 апреля 2010

Да, именно так оно и будет.

...