2011-12-29 80 views
0

我现在有一个系统存储与每个产品关联的产品和标签。将SQL查询合并为相似的结果

产品:话筒

标签:音乐,电子,音响

有一个标签表,产品列表,并TagProductMapping表。第三张表格显然将产品映射到标签以获得一对多的关系。当我使用LEFT JOIN查询Microphone产品时,我得到3条记录几乎是重复的,除了“TagName”列之外,显然它有3个不同的标签。我怎样才能合并这个结果?它令人沮丧,因为如果我试图精确地查询10个产品,它将仅限于10个结果,这不会是10个产品。

任何人都有这个好主意?

编辑:

这里是我的查询结果,发现3点的JobId的之间的不同的唯一事情是如何的类别名称,这是标签。

result query

下面列举一下我的表看起来像

-Tagmapping表:

tagmapping table

-Tag表

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 
+0

你能发表一个表的例子吗? – aleroot 2011-12-29 19:47:29

+0

发布您的查询..您要么使用了错误的连接类型,要么您可能要查看UNION也许您的Inner或Left Outter连接可能是正确的..但是您可能需要子查询或添加/检查空值您的查询以及不能看到表和退出查询 – MethodMan 2011-12-29 19:47:38

+0

标签可以关联到多个产品,并且产品可以有多个标签?如果那是真的,那不是一对多。当您要求“合并”结果时,您是要求仅查看一次产品,然后查看每个标签? – Dan 2011-12-29 19:49:58

回答

1

问题的发生是因为你的数据库结构的标准化标签数据为每个产品(我发现this page是一个很好的参考),我可能是错的。

当你SELECT从Products表和JOIN到你的标签表,它的关键是要记住,你没有得到的产品列表;相反,你得到的产品,标签上的列表组合

如果你想获得。前10名产品列表以及他们的标签i载文信息,我建议使用子查询:

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或无论你使用什么软件层作为中介。

0

我相信,如果你不感兴趣的标签名称,您可以选择除标签名称之外的所有列,并使用“选择不同”来仅显示没有标签的产品。虽然你遇到=(