2009-09-03 1 views
1

Я пытаюсь разобраться в различиях между клиентами, выставленными за последние 3 месяца, и всей клиентской базой. Я был в состоянии рассчитывать клиенты, которые были оплаченные с использованием следующего SQLРазница между двумя наборами данных в SQL Server 2000

DECLARE @DateFrom AS DATETIME 
SET @DateFrom = 
    CONVERT(DATETIME, CAST(YEAR(GETDATE()) AS VARCHAR(4)) + 
    '-' + 
    CAST(MONTH(DATEADD(MONTH, -3, GETDATE())) AS VARCHAR(2)) + '-01', 120) 

DECLARE @DateTo AS DATETIME 
SET @DateTo = 
    CONVERT(DATETIME, CAST(YEAR(GETDATE()) AS VARCHAR(4)) + 
    '-' + 
    CAST(MONTH(GETDATE()) AS VARCHAR(2)) + '-01', 120) 

SELECT DISTINCT 
    i.CustomerCode 
FROM 
    Invoice AS i 
WHERE 
    (i.InvoiceDate > @DateFrom AND i.InvoiceDate < @DateTo) 

В таблице, что я буду против сравнения будет таблицы Customer, который также имеет поле CustomerCode.

Заранее благодарен!

EDIT

прошествию веков, пытаясь понять это, и только через несколько минут отправки сообщения здесь я нашел решение. Используя предложение NOT IN!

SELECT 
    c.CustomerCode 
FROM 
    [Customer] AS c 
WHERE 
    c.CustomerCode NOT IN (
SELECT DISTINCT 
    i.CustomerCode 
FROM 
    [Invoice] AS i 
WHERE 
    (i.InvoiceDate >= @DateFrom AND i.InvoiceDate < @DateTo)) 

В моем senario это, как представляется, выполняется быстрее, чем шаги, упомянутые ниже, когда я тестировал каждый в Management Studio.

+2

и что именно вы хотите? Список всех клиентов, которые не были выставлены счета за последние 3 месяца? Какую версию SQL Server вы используете? –

+0

Именно это. Я использую SQL Server 2000. Есть ли лучшее решение для того, которое у меня есть? – Malachi

+1

Нет, я думаю, что в SQL Server 2000 это примерно так же просто, как и получается. –

ответ

3

вы можете улучшить свое обращение с датой:

WHERE i.InvoiceDate >= DATEADD(mm,-3,DATEADD(mm,DATEDIFF(mm,0,GETDATE()),0)) 
    AND i.InvoiceDate < DATEADD(mm,DATEDIFF(mm,0,GETDATE()),0) 

извещение я> = на старте, вы недостающие строки на дату начала с временем 00:00:00.

, чтобы все клиенты, которые не имеют счета в течение последних 3-х полных месяцев, вы могли бы также написать это так:

SELECT 
    c.CustomerCode 
FROM Customer    c 
    LEFT OUTER JOIN Invoice i ON c.CustomerCode=i.CustomerCode 
     AND i.InvoiceDate >= DATEADD(mm,-3,DATEADD(mm,DATEDIFF(mm,0,GETDATE()),0)) 
     AND i.InvoiceDate < DATEADD(mm,DATEDIFF(mm,0,GETDATE()),0) 
WHERE i.CustomerCode IS NULL 
+0

дата обработка наконечник хороший. Но запрос должен быть изменен так, чтобы проверка диапазона InvoiceDate была частью предложения ON LEFT OUTER JOIN, а не в WHERE. – van

+0

@van, duh, да, он не будет работать с ним в ГДЕ, он должен быть включен в ON –

2

Чтобы получить клиентов, которые не оплаченные в течение некоторого периода времени :

SELECT  c.CustomerCode 
FROM  [Customer] AS c 
LEFT JOIN [Invoice] AS i 
     ON c.CustomerCode = i.CustomerCode 
     AND i.InvoiceDate > @DateFrom AND i.InvoiceDate < @DateTo 
WHERE  i.CustomerCode IS NULL 

Хотя я бы заменить проверку диапазона @DateFrom and @DateTo даты с предложением КМ, чтобы избежать использования переменных.

+0

+1, спасибо за исправление! –