2010-01-04 2 views
1

У меня есть хранимая процедура, которая сортирует pnd пейджинга, как Sorting Custom Paged Results of от Скотта Мичелла.INNER JOIN AND Row_Num() Задачи функции

У меня есть две таблицы: Article и Category. Моя хранимая процедура отлично работает для таблицы Article, но я хочу добавить столбец из таблицы Category в запрос (подразумевается Inner Join I).

На самом деле я не могу сделать это, как это сделал Скотт Мичелл, потому что в обеих таблицах есть похожие столбцы (когда мне все время нравится Скотт, я получаю «Неоднозначную ошибку столбца»).

Моя хранимая процедура без внутреннего соединения является:

set ANSI_NULLS ON 
set QUOTED_IDENTIFIER ON 
go 

ALTER PROCEDURE [dbo].[sp_Articles_SelectByCategoryId] 
    @CategoryId int, 
    @startRowIndex int = -1, 
    @maximumRows int = -1, 
    @sortExpression nvarchar(50), 
    @recordCount int = NULL OUTPUT 
AS 
    IF (@recordCount IS NOT NULL) 
    BEGIN 
     SET @recordCount = (SELECT COUNT(*) 
          FROM [dbo].[Articles] 
          WHERE [CategoryId] = @CategoryId) 
     RETURN 
    END 

    IF LEN(@sortExpression) = 0 
     SET @sortExpression = 'Id' 

    DECLARE @sql nvarchar(4000) 

    SET @sql = 'SELECT [Id], [AddedDate], [AddedBy], [CategoryId], 
         [Title], [Abstract], [Body] 
       FROM 
        (SELECT 
         [Id], [AddedDate], [AddedBy], [CategoryId], 
         [Title], [Abstract], [Body], 
         ROW_NUMBER() OVER(ORDER BY ' + @sortExpression + ') as RowNum 
        FROM [dbo].[Articles] 
        WHERE CategoryId = ' + CONVERT(nvarchar(10), @CategoryId) + ') as CategoryIdInfo 
     WHERE ((RowNum between (' + CONVERT(nvarchar(10), @startRowIndex) + ') AND ' + CONVERT(nvarchar(10), @startRowIndex) + ' + ' + CONVERT(nvarchar(10), @maximumRows) + ' - 1) 
    OR ' + CONVERT(nvarchar(10), @startRowIndex) + ' = -1 OR ' + CONVERT(nvarchar(10), @maximumRows) + ' = -1)' 

     -- Execute the SQL query 
     EXEC sp_executesql @sql 

Мой Category стол:

CREATE TABLE [dbo].[Category] 
(
    [Id] [int] IDENTITY(1,1) NOT NULL, 
    [AddedDate] [datetime] NOT NULL, 
    [AddedBy] [nvarchar](250) COLLATE Arabic_CI_AS NOT NULL, 
    [Title] [nvarchar](50) COLLATE Arabic_CI_AS NOT NULL, 
    [Importance] [int] NOT NULL, 
    [Description] [nvarchar](300) COLLATE Arabic_CI_AS NULL, 
    [ImageUrl] [nvarchar](50) COLLATE Arabic_CI_AS NULL, 

    CONSTRAINT [PK_Category] 
     PRIMARY KEY CLUSTERED ([Id] ASC) 
) 

Мой Article стол:

CREATE TABLE [dbo].[Articles] 
(
    [Id] [int] IDENTITY(1,1) NOT NULL, 
    [AddedDate] [datetime] NOT NULL, 
    [AddedBy] [nvarchar](250) COLLATE Arabic_CI_AS NOT NULL, 
    [CategoryId] [int] NOT NULL, 
    [Title] [nvarchar](255) COLLATE Arabic_CI_AS NOT NULL, 
    [Abstract] [nvarchar](4000) COLLATE Arabic_CI_AS NULL, 
    [Body] [nvarchar](max) COLLATE Arabic_CI_AS NOT NULL, 
    [ReleaseDate] [datetime] NULL, 
    [ExpireDate] [datetime] NULL, 
    [Approved] [bit] NOT NULL, 
    [Listed] [bit] NOT NULL, 
    [CommentEnabled] [bit] NOT NULL, 
    [OnlyForMembers] [bit] NOT NULL, 
    [ViewCount] [int] NOT NULL, 
    [Votes] [int] NOT NULL, 
    [TotalRating] [int] NOT NULL, 
CONSTRAINT [PK_Articles] PRIMARY KEY CLUSTERED 
(
    [Id] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

Я не знаю, как добавить Столбец «Заголовок» таблицы «Категория» в запросе.

Если мой Category стол был не похож поля, конечно, этот запрос работает:

DECLARE @sql nvarchar(4000) 
SET @sql = 
'SELECT 
    [Id], 
    [AddedDate], 
    [AddedBy], 
    [CategoryId], 
    [Title], 
    [Abstract], 
    [Body], 
    ArticleTitle 
FROM 
    (SELECT 

    [Id], 
    [AddedDate], 
    [AddedBy], 
    a.[CategoryId], 
    [Title], 
    [Abstract], 
    [Body], 
    b.Title as CategoryTitle , 
ROW_NUMBER() OVER(ORDER BY ' + @sortExpression + ') as RowNum 

    FROM [dbo].[Articles] a INNER JOIN Category b on a.CategoryId = b.Id 

    WHERE a.CategoryId = ' + CONVERT(nvarchar(10), @CategoryId) + ' 
    ) as CategoryIdInfo 

Если вы хотите проверить, вы можете скачать Attachment(Tables and StoredProcedure) Спасибо

+1

Неоднозначность Ошибка Колонка - Если у вас есть такое же имя столбца, то вы можете претендовать на имя столбца с именем таблицы/псевдоним, так как он не является неоднозначным – David

+0

Мустафы - Ive добавил второй ответ, практически с тем же кодом но на основе вашего примера sproc. Я приправлю это, если это сработает для вас, я просто добавил новый ответ для ясности (и потому, что я беспокоюсь о своем первоначальном ответе на Community Wiki) –

ответ

2

Следующий код отлично работает на ваших предоставленных таблицах - без данных в них, но это не должно иметь значения, поскольку я просто хочу доказать выполнение запроса, а не результаты.

вещи, чтобы отметить с этим кодом:.

выражение сортировки должно включать псевдоним

SET @sortExpression = 'a.Id'  

Все дублированные столбцы должны быть привязаны

Обратите внимание, как [Id] , a. [AddedDate], a. [AddedBy], a. [CategoryId], a. [Title], b. [Title] все псевдонимы

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

Вы имели имя столбца ArticleTitle в вашем внешнем выборе, но в колонке CategoryTitle в вашем внутреннем выборе. Это никогда не сработает.

DECLARE @SortExpression nvarchar(100) 
SET @sortExpression = 'a.Id'   

DECLARE @sql nvarchar(4000) 
SET @sql = 
'SELECT 
    [Id], 
    [AddedDate], 
    [AddedBy], 
    [CategoryId], 
    [Title], 
    [Abstract], 
    [Body], 
    CategoryTitle 
FROM 
    (SELECT 

    a.[Id], 
    a.[AddedDate], 
    a.[AddedBy], 
    a.[CategoryId], 
    a.[Title], 
    [Abstract], 
    [Body], 
    b.Title as CategoryTitle , 
ROW_NUMBER() OVER(ORDER BY ' + @sortExpression + ') as RowNum 

    FROM [dbo].[Articles] a INNER JOIN Category b on a.CategoryId = b.Id 

    WHERE a.CategoryId = ' + CONVERT(nvarchar(10), @CategoryId) + ' 
    ) as CategoryIdInfo' 

     -- Execute the SQL query 
    EXEC sp_executesql @sql 
+0

Дэвид благодарит тонну! Вы мне очень помогли . Если я проведу еще один день, я не смогу решить свою проблему. Что вы думаете об удалении наших предыдущих комментариев, потому что ответ - это сообщение. – Mostafa

0

Вы пробовали что-то вроде кода ниже?

Используется ключевое слово AS для предоставления уникальных имен столбцам в вашем подзапросе и псевдонимов, позволяющих однозначно ссылаться на столбцы внутри самого подзапроса.

Также обратите внимание: ВСЕ ссылки на столбцы, которые являются двусмысленными, должны быть псевдонимами, это включает в ваш случай @sortExpression, который вы динамически впрыскиваете.

ALTER PROCEDURE [dbo].[sp_Articles_SelectByCategoryId] 
@CategoryId int, 
@startRowIndex int = -1, 
@maximumRows int = -1, 
@sortExpression nvarchar(50), 
@recordCount int = NULL OUTPUT 

AS 

IF (@recordCount IS NOT NULL) 
BEGIN 
    SET @recordCount = (SELECT COUNT(*) FROM [dbo].[Articles] WHERE [CategoryId] = @CategoryId 
) 
    RETURN 
END 

IF LEN(@sortExpression) = 0 
    SET @sortExpression = 'Id' 

DECLARE @sql nvarchar(4000) 
SET @sql = 
'SELECT 
[Id], 
[AddedDate], 
[AddedBy], 
[CategoryId], 
[Title], 
-- CategoryTitle refers to the column name declared by that AS inside the subquery 
CategoryTitle 
[Abstract], 
[Body], 

FROM 
(SELECT 

[Id], 
[AddedDate], 
[AddedBy], 
-- The column aliases a and c allow us to refer to similarly names column unambiguously 
a.[CategoryId], 
a.[Title], 
c.[Title] as CategoryTitle, 
[Abstract], 
[Body], 

--- This now includes an alias on the sortExpression order by 
ROW_NUMBER() OVER(ORDER BY a.' + @sortExpression + ') as RowNum 

FROM [dbo].[Articles] a 
Join [dbo].[Category] c 
ON c.CategoryID = a.CategoryID 
WHERE c.CategoryId = ' + CONVERT(nvarchar(10), @CategoryId) + ' 

) as CategoryIdInfo 
WHERE 
((RowNum between (' + CONVERT(nvarchar(10), @startRowIndex) + ') AND ' + CONVERT(nvarchar(10), @startRowIndex) + ' + ' + CONVERT(nvarchar(10), @maximumRows) + ' - 1) 
    OR ' + CONVERT(nvarchar(10), @startRowIndex) + ' = -1 OR ' + CONVERT(nvarchar(10), @maximumRows) + ' = -1)' 

    -- Execute the SQL query 
    EXEC sp_executesql @sql 

Что это делает объявить псевдоним для обеих статей и категорий таблицы (а и с соответственно), что позволяет ссылаться на свои колонки однозначно.

Я не пробовал это с точным случаем использования Row_Number, но не мог думать о причине, почему это не сработает.

Затем использование ключевого слова AS должно дать вам уникальное имя для использования с вашим внешним выбором.

+0

Дэвид, я плохо разбираюсь в sql, но я пробовал каждый который пришел мне на ум. Этот запрос не работает. Я знал, как использовать Alias, но проблема в том, что у меня есть два Select (select,,, ... from (,,,, Rownum .....) – Mostafa

+0

Вы видели часть моего ответа, говорящую о ключе AS для столбца заголовка? Я просто попробовал это с подзапросом, и он работает как ожидалось, позволяя выбирать оба столбца заголовка. –

+0

Кроме того, вы пытались запустить только внутренний запрос с помощью Joins? Я всегда обнаружил, что нарушение –