计数SQL Server

时间:2015-05-20 12:13:56

标签: sql sql-server

我正在编写一个使用分面搜索的产品搜索模块。为了简化一点,有两个实体:产品和价格信息。由于产品可以由多个网上商店出售,因此一个产品可以有更多的价格信息记录。

产品

- product_guid
- product_category
- product_brand

priceInformation

- priceInformation_guid
- priceInformation_price
- priceInformation_product_guid

我列出了特定类别中的所有产品,用户可以按价格范围进行过滤。价格范围列在复选框中,在每个价格范围后面,您可以看到符合搜索条件的产品数量。没有显示没有匹配的价格范围。对于每个价格范围,我会进行查询以确定匹配数(构面数)。

select count(distinct(product.product_guid)) as count
from product 
  INNER JOIN priceInformation ON product.product_guid =
    priceInformation.priceInformation_product_guid
WHERE category= 'beer' 
  AND product.priceInformation_price > 20
  AND product.priceInformation_price <= 30

一切正常但是......因为范围的数量在增长(这只是一个简化的例子)我每次搜索都会执行数百个查询。这是一个重要的性能杀手。我试图在一个查询中获得所有方面计数,但由于产品和priceInformation之间存在1:n关系,因此结果是匹配的价格数量,而不是产品数量。

select (Count(Case WHEN product.priceInformation_price > 20 AND
                        product.priceInformation_price <= 30 THEN 1
                   ELSE NULL END)) as Range2030,
       (Count(Case WHEN product.priceInformation_price > 30 AND
                        product.priceInformation_price <= 40 THEN 1
                   ELSE NULL END)) as Range3040
from product
  INNER JOIN priceInformation ON product.product_guid =
    priceInformation.priceInformation_product_guid
WHERE category= 'beer'

底线是我在这里想念DISTINCT。我把头发拉了几天。有人可以帮忙吗?

2 个答案:

答案 0 :(得分:1)

使用派生表获取不同的价格范围,执行GROUP BY计算不同的价格范围。类似的东西:

select count(distinct(dt.product_guid)), dt.pricerange as count
from
(
 select product.*, case when price < 20 then 'price < 20'
                        when price between 20 and 30 then 'price 20 - 30'
                        else 'price > 30' end as pricerange
 from product
     INNER JOIN priceInformation ON product.product_guid =
    priceInformation.priceInformation_product_guid
 WHERE category= 'beer'
) dt
group by dt.pricerange

或者我现在在这里回答其他问题......?

答案 1 :(得分:0)

我认为您应该创建一个包含价格范围的表格,例如:

create table PriceRanges(minPrice money,maxPrice money);
insert PriceRanges values (0,9),(10,19),(20,29),(100,149) ; 

然后使用此表格查询:

SELECT minPrice,maxPrice,COUNT(DISTINCT p.product_guid)
   as ProductCount
FROM PriceRanges pr
LEFT JOIN priceInformation  pi ON pi.priceInformation_price 
           BETWEEN pr.minPrice AND pr.maxPrice
LEFT JOIN product p ON pi.priceInformation_product_guid= p.product_guid
WHERE p.product_category = 'beer'
GROUP BY minPrice,maxPrice
ORDER BY minPrice

Sqlfiddle demo

如果您不需要空的价格范围,请使用JOIN代替LEFT JOIN。