赋值语句中的SQL Distinct关键字

时间:2010-04-30 21:31:29

标签: sql sql-server tsql distinct

我的查询有效:

DECLARE @ProductID int
SET @ProductID = '1234'

SELECT DISTINCT TOP 12 a.ProductID
FROM A a
WHERE a.CategoryID IN (SELECT b.CategoryID FROM B b WHERE b.ProductID = @ProductID)
AND a.ProductID != @ProductID

它返回一个包含12个产品编号的列表,这些产品编号都是唯一的。

我需要将这些结果存储在变量中,以逗号分隔,因为这是第三方存储过程所需要的。所以我有这个:

 DECLARE @ProductID int
 DECLARE @relatedprods varchar(8000)
 SET @ProductID = '1234'
 SET @relatedprods = ''

 SELECT TOP 12 @relatedprods = @relatedprods + CONVERT(VARCHAR(20), a.ProductID) + ', '
   FROM A a
   WHERE a.CategoryID IN (SELECT b.CategoryID FROM B b WHERE B.ProductID = @ProductID)
   AND a.ProductID != @ProductID

 SELECT @relatedprods

现在,这些都不是明显的,但它返回了12行。

现在我重新添加'distinct',就像在第一个查询中一样:

 DECLARE @ProductID int
 DECLARE @relatedprods varchar(8000)
 SET @ProductID = '1234'
 SET @relatedprods = ''

 SELECT DISTINCT TOP 12 @relatedprods = @relatedprods + CONVERT(VARCHAR(20), a.ProductID) + ', '
   FROM A a
   WHERE a.CategoryID IN (SELECT b.CategoryID FROM B b WHERE B.ProductID = @ProductID)
   AND a.ProductID != @ProductID

 SELECT @relatedprods

逗号分隔列表中只返回一个产品! 'distinct'在赋值语句中不起作用吗?我做错了什么?或者有办法解决这个问题吗?

提前致谢!

结论:

我不知道是什么导致了这个问题,尽管提出的猜测似乎是合乎逻辑的。我能够通过子查询解决这个问题,并发布它,以便其他人可以看到解决方案:

 DECLARE @ProductID int
 DECLARE @relatedprods varchar(8000)
 SET @ProductID = '1234'
 SET @relatedprods = ''

 SELECT @relatedprods = @relatedprods + CONVERT(VARCHAR(20), c.ProductID) + ',' 
    FROM (SELECT DISTINCT TOP 12 a.ProductID FROM A a WHERE a.CategoryID IN 
      (SELECT b.CategoryID 
      FROM B b 
      WHERE B.ProductID = @ProductID) 
    AND a.ProductID != @ProductID ) c

 SET @relatedprods = SUBSTRING(@relatedprods, 0, LEN(@relatedprods))
 SELECT @relatedprods

3 个答案:

答案 0 :(得分:1)

获取子查询中的12条记录:

declare
  @ProductID int,
  @relatedprods varchar(8000)

set @ProductID = '1234'
set @relatedprods = ''

select @relatedprods = @relatedprods + cast(ProductID as varchar) + ','
from (
  select distinct top 12 a.ProductId
  from A a
  inner join B b on b.CategoryID = a.CategoryID
  where  B.ProductID = @ProductID and a.ProductID != @ProductID
) x

答案 1 :(得分:0)

你能使用临时表吗?

DECLARE @relatedProdList TABLE (prod VARCHAR(20))
INSERT INTO @relatedProdList 
SELECT DISTINCT TOP 12 CONVERT(VARCHAR(20), a.ProductID)
FROM A a 
WHERE a.CategoryID IN (SELECT b.CategoryID FROM B b WHERE b.ProductID = @ProductID) 
AND a.ProductID != @ProductID 

SELECT @relatedprods = @relatedprods + prod + ', '
FROM @relatedProdList

答案 2 :(得分:0)

这只是一个疯狂的猜测,但我希望在SELECT中进行分配失败并使用DISTINCT,因为它必须在生成列值后执行排序以强制执行清除。我在添加一个非平凡的ORDER BY子句时看到了类似的行为(例如,通过表达式排序)。

如果您有SQL Server 2005或更高版本,您也可以使用FOR XML PATH

DECLARE @ProductID int
DECLARE @relatedprods varchar(8000)
SET @ProductID = 1234

SET @relatedprods = (SELECT DISTINCT TOP 12
    CONVERT(VARCHAR(20), a.ProductID) + ','
    FROM A a
    WHERE a.CategoryID IN (...)
    AND a.ProductID != @ProductID
    FOR XML PATH(''))

-- FOR XML PATH will add an extra comma at the end, so remove it.
IF LEN(@relatedProds) > 1
    SET @relatedProds = SUBSTRING(@relatedProds, 1, LEN(@relatedProds) - 1)

由于您使用的是子查询而不是变量赋值语法,因此这些限制不适用。