INNER JOIN 和 Row_Num() 函数问题
我有一个存储过程,它对 pnd 分页进行排序,如 对 Scott Michell 的自定义分页结果进行排序。
我有两个表:Article
和 Category
。我的存储过程适用于 Article
表,但我想将 Category
表中的一列添加到查询中(我的意思是内部联接)。
实际上我不能像斯科特·米歇尔那样做,因为两个表中都有一些相似的列(当我一直喜欢斯科特时,我会得到“不明确的列错误”)。
我没有内部联接的存储过程是:
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”表的“Title”列添加到询问。
如果我的 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
如果您想测试,可以下载 附件(表和 StoredProcedure) 谢谢
I have a stored procedure which does sorting pnd Paging like the Sorting Custom Paged Results of by Scott Michell.
I have two tables: Article
and Category
. My stored procedure works fine for Article
table, but I want add a column from the Category
table into the query (Inner Join I mean ).
Actually I can't do it like Scott Michell has done, because there are some columns that are similar in both tables (when I do like Scott all the time I get "Ambiguous Column Error").
My stored procedure without inner join is :
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
My Category
table is :
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)
)
My Article
table :
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]
I don't know how to add The "Title" column of "Category" table into query.
If my Category
table hadn't similar fields, surely this query works :
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
If you want to Test you can download the Attachment(Tables and StoredProcedure)
Thank you
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
以下代码在您提供的表上完美运行 - 其中没有数据,但这应该不会产生影响,因为我只想证明查询执行,而不是结果。
此代码需要注意的事项:
排序表达式必须包含别名
所有重复列都必须有别名
请注意 a.[Id]、a.[AddedDate]、a.[Id]、a.[AddedDate]、a.[Id]、a.[AddedDate]、a. [AddedBy]、a.[CategoryId]、a.[Title]、b.[Title] 都是别名
内部和外部查询之间的列名称必须匹配
您的列名称为 ArticleTitle外部选择,而是内部选择中的一列 CategoryTitle 。那是行不通的。
The following code works perfectly on your provided tables - with no data in them but that shouldn't make a difference since I just want to prove the query execution, not the results.
Things to note with this code:
The sort expression must include an alias
All duplicated columns must be aliased
Note how a.[Id], a.[AddedDate], a.[AddedBy], a.[CategoryId], a.[Title], b.[Title] are all aliased
Column names must match between the inner and outer queries
You had a column name of ArticleTitle in your outer select, but a column of CategoryTitle in your inner select. That would never work.
您是否尝试过类似下面的代码?
这使用 AS 关键字为子查询中的列提供唯一的名称,并使用别名来允许对子查询连接本身中的列进行明确的引用。
另请注意,所有对不明确列的引用必须是别名,这包括您动态注入的 @sortExpression。
其作用是为 Articles 和 Category 表(分别为 a 和 c)声明一个别名,允许您明确地引用它们的列。
我还没有尝试过使用 Row_Number 的确切情况,但想不出它不起作用的原因。
然后使用 AS 关键字应该为您提供一个与外部选择一起使用的唯一名称。
Have you tried something like the code below?
This uses the AS keyword to give unique names to columns in your subquery, and aliases to allow unambiguous references to columns within the subquery join itself.
Also note that ALL references to columns that are ambiguous must be aliases, this includes in your case the @sortExpression that you are dynamically injecting.
What that does is declare an alias for both the Articles and the Category table (a and c respectively) that allows you to reference their columns unambiguously.
I haven't tried this with the exact case of using Row_Number but can think of no reason why it wouldn't work.
Then using the AS keyword should give you a unique name to use with your outer select.