2010-03-19 3 views
2

Я пытаюсь добиться следующего, не используя sub-запрос.Вопрос о SQL-группировке

Для финансирования я хотел бы выбрать самую последнюю созданную дату письма и «самый ранний рабочий список, созданный с момента создания письма» для получения финансирования.

 
FundingId Leter (1, 1/1/2009)(1, 5/5/2009) (1, 8/8/2009) (2, 3/3/2009) 

FundingId WorkList (1, 5/5/2009) (1, 9/9/2009) (1, 10/10/2009) (2, 2/2/2009) 

Ожидаемый результат -

 
FundingId Leter WorkList (1, 8/8/2009, 9/9/2009) 

Я написал запрос следующим образом. У него есть ошибка. Он будет опускать те FundingId, для которых минимальная дата WorkList меньше, чем последняя дата письма (даже если у нее есть другой рабочий список с датой, большей, чем дата письма).

CREATE TABLE #Funding(
[Funding_ID] [int] IDENTITY(1,1) NOT NULL, 
[Funding_No] [int] NOT NULL, 
CONSTRAINT [PK_Center_Center_ID] PRIMARY KEY NONCLUSTERED ([Funding_ID] ASC) 
) ON [PRIMARY] 

CREATE TABLE #Letter(
[Letter_ID] [int] IDENTITY(1,1) NOT NULL, 
[Funding_ID] [int] NOT NULL, 
[CreatedDt] [SMALLDATETIME], 
CONSTRAINT [PK_Letter_Letter_ID] PRIMARY KEY NONCLUSTERED ([Letter_ID] ASC) 
) ON [PRIMARY] 

CREATE TABLE #WorkList(
[WorkList_ID] [int] IDENTITY(1,1) NOT NULL, 
[Funding_ID] [int] NOT NULL, 
[CreatedDt] [SMALLDATETIME], 
CONSTRAINT [PK_WorkList_WorkList_ID] PRIMARY KEY NONCLUSTERED ([WorkList_ID] ASC) 
) ON [PRIMARY] 

SELECT F.Funding_ID, 
Funding_No, 
MAX (L.CreatedDt), 
MIN(W.CreatedDt) 
FROM #Funding F 
INNER JOIN #Letter L ON L.Funding_ID = F.Funding_ID 
LEFT OUTER JOIN #WorkList W ON W.Funding_ID = F.Funding_ID 
GROUP BY F.Funding_ID,Funding_No 
HAVING MIN(W.CreatedDt) > MAX (L.CreatedDt) 

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

Пожалуйста, помогите

Благодарности

Lijo

+1

этот сервер sql? –

+0

Да. Это находится в SQL Server 2005 – Lijo

ответ

1

с использованием производных таблиц так же хорошо, как он получает: таблицы

OP в:

CREATE TABLE #Funding(
[Funding_ID] [int] IDENTITY(1,1) NOT NULL, 
[Funding_No] [int] NOT NULL, 
CONSTRAINT [PK_Center_Center_ID] PRIMARY KEY NONCLUSTERED ([Funding_ID] ASC) 
) ON [PRIMARY] 

CREATE TABLE #Letter(
[Letter_ID] [int] IDENTITY(1,1) NOT NULL, 
[Funding_ID] [int] NOT NULL, 
[CreatedDt] [SMALLDATETIME], 
CONSTRAINT [PK_Letter_Letter_ID] PRIMARY KEY NONCLUSTERED ([Letter_ID] ASC) 
) ON [PRIMARY] 

CREATE TABLE #WorkList(
[WorkList_ID] [int] IDENTITY(1,1) NOT NULL, 
[Funding_ID] [int] NOT NULL, 
[CreatedDt] [SMALLDATETIME], 
CONSTRAINT [PK_WorkList_WorkList_ID] PRIMARY KEY NONCLUSTERED ([WorkList_ID] ASC) 
) ON [PRIMARY] 

образец данных OP в:

INSERT INTO #Funding (Funding_No) VALUES (1) 
INSERT INTO #Funding (Funding_No) VALUES (2) 

INSERT INTO #Letter (Funding_ID,CreatedDt) VALUES (1,'1/1/2009') 
INSERT INTO #Letter (Funding_ID,CreatedDt) VALUES (1,'5/5/2009') 
INSERT INTO #Letter (Funding_ID,CreatedDt) VALUES (1,'8/8/2009') 
INSERT INTO #Letter (Funding_ID,CreatedDt) VALUES (2,'3/3/2009') 

INSERT INTO #WorkList (Funding_ID,CreatedDt) VALUES (1, '5/5/2009') 
INSERT INTO #WorkList (Funding_ID,CreatedDt) VALUES (1, '9/9/2009') 
INSERT INTO #WorkList (Funding_ID,CreatedDt) VALUES (1, '10/10/2009') 
INSERT INTO #WorkList (Funding_ID,CreatedDt) VALUES (2, '2/2/2009') 

В таблице СОЗДАЕТ выглядеть TSQL, но ни одна из версий не было учитывая, что CTE также может быть использован. Однако, это использует производные таблицы:

SELECT 
    dt.Funding_ID,LCreatedDt,MIN(CreatedDt) AS WCreatedDt 
    FROM (SELECT 
       f.Funding_Id,l.LCreatedDt 
       FROM #Funding f 
       LEFT OUTER JOIN (SELECT 
            Funding_ID,MAX(CreatedDt) AS LCreatedDt 
            FROM #Letter 
            GROUP BY Funding_ID 
          ) l ON f.Funding_ID=l.Funding_ID 
     ) dt 
    LEFT OUTER JOIN #WorkList w ON dt.Funding_ID=w.Funding_ID 
    WHERE w.CreatedDt>dt.LCreatedDt 
    GROUP BY dt.Funding_ID,LCreatedDt 

ВЫВОД:

Funding_ID LCreatedDt    WCreatedDt 
----------- ----------------------- ----------------------- 
1   2009-08-08 00:00:00  2009-09-09 00:00:00 

(1 row(s) affected) 

упредить какие-то люди утверждают, что мой запрос использует подзапрос, прочитайте эту статью на подзапрос Основы: http://msdn.microsoft.com/en-us/library/aa213252(SQL.80).aspx

Подзапрос - это запрос SELECT, который возвращает одно значение и является вложенным внутри SELECT, INSERT, UPDATE, или Оператор DELETE или внутри другого подзапроса . Подзапрос может использоваться в любом месте, где разрешено выражение.

+0

Ответ: –

+0

Спасибо. Оно работает.Я использовал CTE, чтобы сделать его более читаемым. – Lijo

1

Ваш вопрос How can I write a correct query without using subquery?

Но вы не используете подзапрос ... так у вас уже есть свой ответ.

+0

В приведенном выше запросе отсутствует ошибка. (Я изложил это в описании как «Я написал запрос следующим образом: у него есть ошибка. Он будет опускать те FundingId, для которых минимальная дата WorkList меньше, чем последняя дата письма (даже если у нее есть другой рабочий список с больше, чем дата создания письма). " Пожалуйста, помогите. – Lijo