2012-02-10 22 views
-1

プロシージャ内の最後のselect文に無効な列名があります。私はThreadTitleを取得する必要があり、列ThreadIDによって選択されています。ローカル変数を使用することはできませんし、F.ForumD選択句のために設定することはできません。私はちょうど、誰もが、我々はすべてのスキーマを持っていないので無効な列名は変数を使用できません

SELECT ForumGroup = (
    CASE WHEN ParentID IS NOT NULL THEN 
    (SELECT Title FROM Forums WHERE ForumID = F.ParentID)   
    ELSE 
    (SELECT Title FROM Forums WHERE ParentID IS NULL) 
    END), 
    Title, 
    Description, 
    ThreadCount = (SELECT COUNT(*) FROM Posts P WHERE P.ForumID = F.ForumID), 
    LastPostBy = (SELECT TOP 1 AddedBy FROM Posts P 
    WHERE P.ForumID = F.ForumID ORDER BY P.PostID DESC), 
    LastPostDate = (SELECT TOP 1 AddedDate FROM Posts P 
    WHERE P.ForumID = F.ForumID ORDER BY P.PostID DESC), 
    LastPostTitle = (SELECT TOP 1 Title FROM Posts P 
    WHERE P.ForumID = F.ForumID ORDER BY P.PostID DESC), 
    ThreadID = CAST(SUBSTRING((SELECT TOP 1 Path_String 
    FROM Posts P WHERE P.ForumID = F.ForumID ORDER BY P.PostID DESC), 0, 
    CHARINDEX('/', (SELECT TOP 1 Path_String FROM Posts P 
    WHERE P.ForumID = F.ForumID ORDER BY P.PostID DESC))) AS INT), 
    ThreadTitle = (SELECT TOP 1 Title FROM Posts P 
    WHERE P.PostID = ThreadID ORDER BY P.PostID DESC) 
    FROM Forums F WHERE ParentID IS NOT NULL 
    ORDER BY Title 
+2

これはC#またはASP.NETとどのように関連していますか?これは純粋な[t-sql](http://stackoverflow.com/questions/tagged/tsql)の質問です。 –

+1

2つのテーブル作成ステートメントを投稿できますか?予期した結果とともにいくつかのサンプルの挿入を与えることができれば、本当に役に立ちます。 –

+0

ポストタイトルとスレッドタイトルの違いは何ですか?言及/参照を忘れたスレッドテーブルはありますか? –

答えて

1

は、私が何についての両方の前提で、いくつかの自由を取るつもりだことを行う方法を知っているんThreadIDを取得し、ThreadTitleにそれを渡す必要がありますあなたは何を持っているべきかについて提案しています。これらは、このクエリを満たすのに適しているので、塩分でこれらのものを取るべきです。これらの提案が他のクエリに与える影響についてはわかりません。

私はベーステーブルで推測するつもりです:今

USE tempdb; 
GO 

CREATE TABLE dbo.Forums 
(
    ForumID  INT PRIMARY KEY, 
    Title  VARCHAR(32), 
    Description VARCHAR(255), 
    ParentID INT NULL FOREIGN KEY REFERENCES dbo.Forums(ForumID) 
); 
CREATE INDEX t ON dbo.Forums(ParentID); 
GO 

CREATE TABLE dbo.Threads 
(
    ThreadID INT PRIMARY KEY, 
    Title VARCHAR(32) 
); 
GO 

CREATE TABLE dbo.Posts 
(
    PostID  INT PRIMARY KEY, 
    AddedBy  VARCHAR(32), 
    AddedDate DATETIME, 
    Title  VARCHAR(32), 
    Path_String VARCHAR(255), 
    ForumID  INT FOREIGN KEY REFERENCES dbo.Forums(ForumID) 
); 
CREATE INDEX f ON dbo.Posts(ForumID, PostID DESC) INCLUDE(AddedBy, AddedDate, Title); 
GO 

Path_Stringはほぼ確実に一度だけ書かれているので、あなたがこの永続化計算列作り、それをインデックスから大きな利益を得ることができます。この方法では、行が挿入されたときにのみ、その高価な部分文字列を計算するというペナルティを支払うことになります。代わりにこれらの事で

ALTER TABLE dbo.Posts ADD ThreadID AS 
    CONVERT(INT,SUBSTRING(Path_String, 0, CHARINDEX('/', Path_String))) 
    PERSISTED FOREIGN KEY REFERENCES dbo.Threads(ThreadID); 

CREATE INDEX t ON dbo.Posts(ThreadID); 

CREATE INDEX f ON dbo.Posts(ForumID, PostID DESC) 
    INCLUDE(AddedBy, AddedDate, Title, ThreadID) WITH (DROP_EXISTING = ON); 
GO 

、クエリのように書き換えることができます。

;WITH p AS 
(
    SELECT PostID, AddedBy, AddedDate, Title, ForumID, ThreadID, 
     rn = ROW_NUMBER() OVER (PARTITION BY ForumID ORDER BY PostID DESC), 
     c = COUNT(*)  OVER (PARTITION BY ForumID) 
    FROM dbo.Posts 
) 
SELECT 
    ForumGroup = fp.Title, 
    f.Title, 
    f.Description, 
    ThreadCount = p.c, 
    LastPostBy = p.AddedBy, 
    LastPostDate = p.AddedDate, 
    LastPostTitle = p.Title, 
    ThreadID  = p.ThreadID, 
    ThreadTitle = t.Title 
FROM dbo.Forums AS f 
    INNER JOIN p      ON p.ForumID = f.ForumID 
    LEFT OUTER JOIN dbo.Threads AS t ON t.ThreadID = p.ThreadID 
    LEFT OUTER JOIN dbo.Forums AS fp ON fp.ForumID = f.ParentID 
WHERE p.rn = 1 
AND f.ParentID IS NOT NULL 
ORDER BY f.Title; 

実行計画を比較することはお気軽に。使用しているすべてのサブクエリのため、あなたのバージョンのクエリでは、より多くのスキャン/シーク/ネストされたループが表示されます。

もちろん、サンプルデータと望みの結果がなければ、あなたが書いた質問(自分の答えに基づいている)があなたに必要な結果を得ているかどうかはわかりません。しかし、うまくいけばもっと詳しく説明します。

1

fre最後のselectでTreadIDの代わりに使用するselectステートメントでTreadIDを取得しようとしていますか?あなたは同じクエリを使用してTreadIDで置き換えることができます。

SELECT ForumGroup = ( 
     CASE WHEN ParentID IS NOT NULL THEN 
     (SELECT Title FROM Forums WHERE ForumID = F.ParentID)    
     ELSE 
     (SELECT Title FROM Forums WHERE ParentID IS NULL) 
     END), 
     Title, 
     Description, 
     ThreadCount = (SELECT COUNT(*) 
        FROM Posts P 
        WHERE P.ForumID = F.ForumID), 
     LastPostBy = (SELECT TOP 1 AddedBy 
        FROM Posts P 
        WHERE P.ForumID = F.ForumID 
        ORDER BY P.PostID DESC), 
     LastPostDate = (SELECT TOP 1 AddedDate 
         FROM Posts P 
         WHERE P.ForumID = F.ForumID 
         ORDER BY P.PostID DESC), 
     LastPostTitle = (SELECT TOP 1 Title 
         FROM Posts P 
         WHERE P.ForumID = F.ForumID 
         ORDER BY P.PostID DESC), 
     ThreadID = CAST(SUBSTRING((SELECT TOP 1 Path_String 
            FROM Posts P 
            WHERE P.ForumID = F.ForumID 
            ORDER BY P.PostID DESC), 0, CHARINDEX('/', (SELECT TOP 1 Path_String 
                       FROM Posts P 
                       WHERE P.ForumID = F.ForumID 
                       ORDER BY P.PostID DESC) 
                     ) 
           ) AS INT), 
     ThreadTitle = (SELECT TOP 1 Title 
        FROM Posts P 
        WHERE P.PostID = (CAST(SUBSTRING((SELECT TOP 1 Path_String 
                 FROM Posts P 
                 WHERE P.ForumID = F.ForumID 
                 ORDER BY P.PostID DESC), 0, CHARINDEX('/', (SELECT TOP 1 Path_String 
                            FROM Posts P 
                            WHERE P.ForumID = F.ForumID 
                            ORDER BY P.PostID DESC) 
                           ) 
                 ) AS INT)) 
        ORDER BY P.PostID DESC 
        ) 
     FROM Forums F WHERE ParentID IS NOT NULL 
     ORDER BY Title 
+0

私は、ThreadTitleとPostTitleが同じではないと思います(つまり、ThreadTitleはPostsテーブルから来てはなりません)。 –

+0

私は彼の質問には..私はdataschemaを知らない。私は@ KDMの質問から私が理解するものに基づいて私の答えを与えた。 – AJP

関連する問題