2011-12-29 76 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

我相信,如果你不感興趣的標籤名稱,您可以選擇除標籤名稱之外的所有列,並使用「選擇不同」來僅顯示沒有標籤的產品。雖然你遇到=(