sql-serverquery-designer

How do I properly add this query into my existing query within Query Designer?


I currently have the below query written within Query Designer. I asked a question yesterday and it worked on its own but I would like to incorporate it into my existing report.

SELECT Distinct
       i.ProductNumber
  ,i.ProductType
  ,i.ProductPurchaseDate
  ,ih.SalesPersonComputerID
  ,ih.SalesPerson
  ,ic2.FlaggedComments

FROM [Products] i
        
LEFT OUTER JOIN 
    (SELECT Distinct
        MIN(c2.Comments) AS FlaggedComments
        ,c2.SalesKey 
        FROM [SalesComment] AS c2
        WHERE(c2.Comments like 'Flagged*%')
        GROUP BY c2.SalesKey) ic2 
    ON ic2.SalesKey = i.SalesKey

LEFT JOIN [SalesHistory] AS ih
    ON ih.SalesKey = i.SalesKey

WHERE
  i.SaleDate  between @StartDate and @StopDate
AND ih.Status = 'SOLD'

My question yesterday was that I wanted a way to select only the first comment made for each sale. I have a query for selecting the flagged comments but I want both the first row and the flagged comment. They would both be pulling from the same table. This was the query provided and it worked on its own but I cant figure out how to make it work with my existing query.

SELECT a.DateTimeCommented, a.ProductNumber, a.Comments, a.SalesKey 
FROM (
    SELECT 
            DateTimeCommented, ProductNumber, Comments, SalesKey,
            ROW_NUMBER() OVER(PARTITION BY ProductNumber ORDER BY DateTimeCommented) as RowN
    FROM [SalesComment]
    ) a 
WHERE a.RowN = 1

Thank you so much for your assistance.


Solution

  • You can use a combination of row-numbering and aggregation to get both the Flagged% comments, and the first comment.

    You may want to change the PARTITION BY clause to suit.

    DISTINCT on the outer query is probably spurious, on the inner query it definitely is, as you have GROUP BY anyway. If you are getting multiple rows, don't just throw DISTINCT at it, instead think about your joins and whether you need aggregation.

    The second LEFT JOIN logically becomes an INNER JOIN due to the WHERE predicate. Perhaps that predicate should have been in the ON instead?

    SELECT
       i.ProductNumber
      ,i.ProductType
      ,i.ProductPurchaseDate
      ,ih.SalesPersonComputerID
      ,ih.SalesPerson
      ,ic2.FlaggedComments
      ,ic2.FirstComments
    
    FROM [Products] i
            
    LEFT OUTER JOIN 
        (SELECT
            MIN(CASE WHEN c2.RowN = 1 THEN c2.Comments) AS FirstComments
            ,c2.SalesKey 
            ,MIN(CASE WHEN c2.Comments like 'Flagged*%' THEN c2.Comments) AS FlaggedComments
            FROM (
                SELECT *,
                  ROW_NUMBER() OVER (PARTITION BY ProductNumber ORDER BY DateTimeCommented) as RowN
                FROM [SalesComment]
            ) AS c2
            GROUP BY c2.SalesKey
        ) ic2 ON ic2.SalesKey = i.SalesKey
    
    JOIN [SalesHistory] AS ih
        ON ih.SalesKey = i.SalesKey
    
    WHERE
      i.SaleDate between @StartDate and @StopDate
    AND ih.Status = 'SOLD'