合并SQL查询以获得相似的结果

时间:2011-12-29 19:45:33

标签: c# asp.net sql sql-server

我现在有一个系统,用于存储与每个产品相关的产品和标签。

实施例

产品:麦克风

标签:音乐,电子产品,音频

有一个Tag表,Product Table和TagProductMapping Table。第三个表格显然将产品映射到一对多关系的标签。当我使用LEFT JOIN查询Microphone产品时,我获得了几乎重复的3条记录,除了“TagName”列,显然它有3个不同的标签。如何合并此结果?令人沮丧的是因为如果我尝试查询10个产品,它只会限制为10个结果,这实际上不是10个产品。

有人对此有好主意吗?

编辑:

以下是我查询的结果,请注意3个JobId之间唯一不同的是CategoryName,它们是标签。

result query

以下是我的表格的样子

-Tagmapping table:

tagmapping table

-Tag Table

tag table

- “产品表”(在本例中,是我的工作表)

enter image description here

这是我的存储过程:

ALTER PROCEDURE [dbo].[JobPostingSelectAll]                       
(                      
    @StartRowIndex     INT,                      
    @PageSize          INT,                      
    @OrderBy           VARCHAR(50),                      
    @OrderByDirection  VARCHAR(4),                      
    @CurrentUserId     INT,            
    @CategoryId     INT                      
)                      
AS                      
 SET NOCOUNT ON                                            



 SELECT         
  JobId,        
  Title,                      
  Answers,          
  UserId,                  
        UserName,        
        ProfileImageName,        
        CategoryId,        
        CategoryName,        
        Fees,            
        DESCRIPTION,                
        DateCreated,      
        UniqueTitle,    
        IsSecured                                
 FROM   (                      
            SELECT J.JobId,        
       J.Title,        
       (SELECT COUNT(ja2.JobId) FROM JobApplication ja2 left join Deliverable d2 ON d2.DeliverableId = ja2.DeliverableId
       WHERE ja2.JobId=j.JobId and (d2.PurchaseCount>0 OR d2.IsFrozen=0)) AS Answers,            
                   J.UserId,        
                   U.UserName,        
                   U.ImageName as ProfileImageName,        
                   J.CategoryId,        
                   C.CategoryName,        
                   J.Fees,        
                   J.Description,                                              
                   J.DateCreated,      
                   J.UniqueTitle,    
                   J.IsSecured,                                                
                   ROW_NUMBER() OVER(                      
                       ORDER BY                  
                       CASE                       
                            WHEN @OrderByDirection = 'asc' AND @OrderBy = 'Answers'             
                            THEN (SELECT COUNT(ja2.JobId) FROM JobApplication ja2 left join Deliverable d2 ON d2.DeliverableId = ja2.DeliverableId
       WHERE ja2.JobId=j.JobId and (d2.PurchaseCount>0 OR d2.IsFrozen=0)) END ASC,            
                       CASE                       
                            WHEN @OrderByDirection = 'asc' AND @OrderBy = 'Answers'             
                            THEN J.DateCreated END DESC,            
                       CASE                       
                            WHEN @OrderByDirection = 'asc' AND @OrderBy = 'Answers'             
                            THEN J.Title END ASC,            
                       CASE                       
                            WHEN @OrderByDirection = 'desc' AND @OrderBy = 'Answers'             
                            THEN (SELECT COUNT(ja2.JobId) FROM JobApplication ja2 left join Deliverable d2 ON d2.DeliverableId = ja2.DeliverableId
       WHERE ja2.JobId=j.JobId and (d2.PurchaseCount>0 OR d2.IsFrozen=0)) END DESC,                                             
      CASE                       
                            WHEN @OrderByDirection = 'desc' AND @OrderBy = 'Answers'             
                            THEN J.DateCreated END DESC,            
                         CASE                       
                            WHEN @OrderByDirection = 'desc' AND @OrderBy = 'Answers'             
                            THEN J.Title END ASC,            
                       CASE WHEN @OrderByDirection = 'asc' AND @OrderBy = 'Fees'             
       THEN J.Fees END ASC,            
       CASE WHEN @OrderByDirection = 'asc' AND @OrderBy = 'Fees'             
       THEN J.DateCreated END DESC,            
        CASE WHEN @OrderByDirection = 'desc' AND @OrderBy = 'Fees'             
       THEN J.Fees END DESC,            
                       CASE WHEN @OrderByDirection = 'desc' AND @OrderBy = 'Fees'             
       THEN J.DateCreated END DESC,            
                       CASE WHEN @OrderByDirection = 'asc' AND @OrderBy = 'DateCreated'             
       THEN J.DateCreated END ASC,                      
                       CASE WHEN @OrderByDirection = 'desc' AND @OrderBy = 'DateCreated'             
       THEN J.DateCreated END DESC            
                   ) AS RowIndex           
            FROM   [JobPosting] J    
                LEFT JOIN TagMapping TM ON J.JobId = TM.QuestionId      
                        LEFT JOIN Categories C ON TM.TagId = C.CategoryID            
            Left Join [User] U ON J.UserId = U.UserID            
            WHERE  J.IsLocked = 0  AND j.IsDeleted = 0                                           
       AND (@CategoryId IS NULL OR  J.CategoryId = @CategoryId)            

        ) AS JobPostingList                      
 WHERE  RowIndex BETWEEN @StartRowIndex AND (@StartRowIndex + @PageSize) - 1             


 SELECT COUNT(J.JobID) AS TotalRecords                      
 FROM   JobPosting J                                      
 WHERE  J.IsLocked = 0 AND J.IsDeleted = 0                        
        AND (@CategoryId IS NULL OR  J.CategoryId = @CategoryId)          


-- select all filecount grouped by Type Of File for specific Job                
SELECT J.JobId, F.MimeType, COUNT(F.FileId) AS FileCount                
FROM                   
JobPosting J  
Left Join Files F ON  F.JobPostingId = J.JobId  
WHERE  J.IsLocked = 0 AND J.IsDeleted = 0                        
        AND (@CategoryId IS NULL OR  J.CategoryId = @CategoryId)          
GROUP BY                                
       F.MimeType,J.JobId  
Having COUNT(F.FileId) > 0

2 个答案:

答案 0 :(得分:1)

您遇到的问题是因为您的数据库结构规范了每个产品的标记数据(我发现this page是一个很好的参考)。

当您从Products表SELECTJOIN到您的Tags表时,记住您没有获得产品列表是至关重要的;相反,您将获得Product-Tag 组合的列表

如果您想获得前10个产品的列表以及他们的标签信息,我建议您使用子查询:

select * from 
    (select top 10 * from ProductsTable) TopProducts
    inner join Tagmapping on TopProducts.ProductID = Tagmapping.ProductID
    inner join Tags on Tagmapping.TagID = Tags.TagID

即使这解决了您的初始选择问题,这仍然会产生您在上面显示的多个列表,其中只有标记信息因行而异。

可以将输出格式化为具有多个标记条目(可能用逗号分隔)as described here,但在将数据呈现给用户之前,这将是您想要做的最后一步。通过SQL或您用作中间人的任何软件层。

答案 1 :(得分:0)

我相信如果您对标签名称不感兴趣,可以选择除标签名称以外的所有列,并使用“select distinct”仅显示没有标签的产品。我可能错了=(