如何从存储过程中选择唯一记录

时间:2014-01-21 06:23:31

标签: sql-server stored-procedures dynamic-sql distinct-values

存储过程是

alter PROCEDURE [dbo].[Get_ProductsByCategoryId_Filter]
 @CategoryId int,
 @BrandId int,
     @PageSize int,
       @PageIndex int

 AS
        SET NOCOUNT ON

 DECLARE @ParamDefinition AS NVARCHAR(2000) 

DECLARE @sql nvarchar(4000)

SET @sql =     'select  DISTINCT   ProductId,  Name, Description,ProductPriceId,Price,Size,Weight,ThumbnailFilename,BrandId,DeliveryId,CategoryId,HasFreeWrapping,IsPharmaceutical,BrandCategoryId,Enabled,OpenForOffer,FreeDeliveryInUK,Discontinued,EnforceStockCount,OnlyInUK,ShowPreOrderButton,MinPrice
                from (SELECT   P.[ProductId], P.[Name], P.[Description],PP.[ProductPriceId],PP.[Price],PP.[Size],PP.[Weight], M.[ThumbnailFilename],M.[MEDIAFILENAME], P.[BrandId], P.[DeliveryId], P.[CategoryId], P.[HasFreeWrapping], P.[IsPharmaceutical], P.[BrandCategoryId], P.[Enabled], P.[OpenForOffer], P.[FreeDeliveryInUK], 
                               P.[Discontinued], P.[EnforceStockCount], P.[OnlyInUK], P.[ShowPreOrderButton], MIN(ISNULL(PP.[Price], 0)) AS [MinPrice],
                                ROW_NUMBER() OVER (Order By  P.ProductId asc) AS 
                                RowRank 
                         FROM [Products] P  WITH (NOLOCK)
                        LEFT JOIN [ProductPrices] PP  WITH (NOLOCK) ON PP.[ProductId] = P.[ProductId]
                        INNER JOIN [ProductCategory] PC  WITH (NOLOCK) ON   P.[ProductId] =   PC.[ProductId]
                        INNER JOIN [Categories] C  WITH (NOLOCK) ON C.[CategoryId] = PC.[CategoryId] 
                        inner join [Brands] b  WITH (NOLOCK) ON  P.[brandid]= b.[brandid]
                        inner join [ProductMedia] m with (NOLOCK) ON P.[PRODUCTID]= M.[PRODUCTID]
                     WHERE 1 = 1 AND P.Enabled = 1 AND P.Discontinued = 0 AND PP.Stock > 0 AND (C.[CATEGORYID]=@CategoryId or  @CategoryId=0)   AND (P.[BRANDID]=@BrandId or @BrandId is null)
                     AND M.PRODUCTMEDIAID = (SELECT DISTINCT TOP 1 PRODUCTMEDIAID FROM PRODUCTMEDIA WHERE PRODUCTMEDIA.PRODUCTID=  P.PRODUCTID)
 GROUP BY P.[ProductId], P.[Name], P.[Description],PP.[ProductPriceId],PP.[Price],PP.[Size],PP.[Weight], M.[ThumbnailFilename],M.[MEDIAFILENAME], P.[BrandId],B.[BrandId], P.[DeliveryId], P.[CategoryId], P.[HasFreeWrapping], P.[IsPharmaceutical], P.[BrandCategoryId], P.[Enabled], P.[OpenForOffer], P.[FreeDeliveryInUK], P.[Discontinued], P.[EnforceStockCount], P.[OnlyInUK], P.[ShowPreOrderButton]
                    ) AS ProductsWithRowNumbers
            WHERE

            RowRank > ' + CONVERT(nvarchar(10), @PageIndex ) +
                ' AND RowRank <= (' + CONVERT(nvarchar(10), 
@PageIndex) + ' + '
                + CONVERT(nvarchar(10), @PageSize) + ') '


              SET @ParamDefinition = '@CategoryId int,@BrandId int, @PageSize int,
    @PageIndex int
   '


-- Execute the SQL query

EXEC sp_executesql @sql, @ParamDefinition,                        
                         @CategoryId,
                         @BrandId,
                          @PageSize ,
                                                    @PageIndex 


-- 

GO

在上面的存储过程的结果中,我得到重复的记录,但我不想显示重复的记录,请帮助我如何获得

2 个答案:

答案 0 :(得分:0)

当你使用DISTINCT时,你似乎重复的不是真正的重复。可能,重复数据仍然包含不同的值。

更新:虽然您需要唯一的ProductId并且想要从非唯一数据中挑选任何数据(对应于一个ProductId的不同记录),您需要在ProductId上使用GROUP BY,并在所有其他字段上使用MAX等其他聚合函数:

SELECT ProductId, MAX(Name), MAX(Description)...
GROUP BY ProductId

如果你确实需要FIRST / ANY聚合的功能(SQL Server缺少这些聚合),请尝试像这里的CROSS APPLY技巧:http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=60565&whichpage=2#721589或CTE技巧,如:SQL Server pick random (or first) value with aggregation或者,如果你使用SQL Server 2012+,请尝试FIRST_VALUE analytic function

答案 1 :(得分:0)

我知道这已经过时了,但可能会为遇到问题的人清理一些事情。

首先,如果行中的某些内容不同,则不会获得重复记录。当您执行DISTINCT查询时,例如:

Select DISTINCT productID, salesID, name, time
FROM yourtable

然后SQL会找到不同的ROWS,而不是列中的特定项。

因此,如果任何列都有不同的数据,它会将该行标识为与其他列不同....这可能看起来像是在重复,但唉,情况并非如此。

如果您需要不同产品ID的列表,请检查存储过程的代码并找到产品ID的来源,在这种情况下:[产品]

所以,如果你想真正区分,那么:

Select DISTINCT ProductID
FROM [Products]

当然,由于你不需要上面代码中的DISTINCT,我很滑稽......你肯定不会得到你想要的信息。确定您需要更多放大信息,因此请使用SELECT * FROM Products查找所需产品中的哪些列,并在存储过程的不同查询中使用它们(仅限它们)。这应该为您提供不同的行,显示查询中包含的产品。

塔塔