2010-03-19 52 views
2

我試圖在不使用子查詢的情況下實現以下功能。關於SQL分組的問題

對於資金來說,我想選擇最新的Letter創建日期和'創建信件之後創建的最早的工作列表'以獲得資助。

 
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。

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服務器? – 2010-03-19 13:08:10

+0

是的。它在SQL Server 2005中 – Lijo 2010-03-22 07:13:28

回答

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 

OUTPUT:

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

這是答案:) – 2010-03-19 13:31:06

+0

謝謝。有用。我已經使用CTE使其更具可讀性。 – Lijo 2010-03-22 07:12:31

1

你的問題是How can I write a correct query without using subquery?

但你不使用子查詢......所以你已經有你的答案。

+0

上面的查詢沒有錯誤。 (我在說明中聲明它爲 「我寫了一個查詢,如下所示:它有一個錯誤,它將省略那些最低WorkList日期小於最新Letter日期的FundingId(即使它有另一個工作列表大於字母創建日期)「 請幫忙。 – Lijo 2010-03-19 10:53:23