2017-11-04 44 views
1

TOP我有两个表:替代SQL ANSI与TIES

产品

  • id_product
  • 描述
  • 价格
  • id_category

  • id_category
  • 描述

我想知道,有更多的产品类别。例如,类别食品也有10种产品和电子产品。他们是一样的。

现在我正在使用SQL Server,并使用TOP WITH TIES。

SELECT TOP 1 WITH TIES p.id_category, COUNT(*) as amount FROM product p 
JOIN category c ON p.id_category = c.id_category 
GROUP BY p.id_category 
ORDER BY amount 

是否有另一种方法来解决这一问题,并获得良好的性能? 我也试着用DENSE_RANK的位置= 1。 它也有效。

SELECT * FROM (
SELECT p.id_category, COUNT(*) as amount, DENSE_RANK() OVER (ORDER BY COUNT(*) DESC) position FROM product p 
JOIN category c ON p.id_category = c.id_category 
GROUP BY p.id_category 
) rnk 
WHERE rnk.position = 1 

但我想在SQL ANSI这个解决方案。

我尝试使用MAX(COUNT(*)),但它不起作用。

是否有一个通用的解决方案?这种解决方案比使用TOP WITH TIES更好吗?

+0

当你使用MAX(COUNT(*))'时,你是否尝试在'HAVING'中使用它? – Alan

+1

稠密等级_is_是ANSI SQL标准的一部分,只有在使用MySQL或少数其他数据库时才可用。依靠密集排名的问题是什么? –

+0

我尝试使用SUBSELECT ON必须获得最大值。但是我应该重复一下这些代码吗 – OnScreen

回答

2

下面是SQL Server中的第三个选项:

WITH cte AS (
    SELECT p.id_category, COUNT(*) AS cnt 
    FROM product p 
    INNER JOIN category c 
     ON p.id_category = c.id_category 
    GROUP BY p.id_category 
) 

SELECT * 
FROM cte 
WHERE cnt = (SELECT MAX(cnt) FROM cte); 

如果你也不能依靠热膨胀系数可用,你可以简单的只是内联CTE进入查询。从性能角度来看,DENSE_RANK可能会超出我的答案。

随着CTE移除了这个变成:

SELECT * 
FROM 
(
    SELECT p.id_category, COUNT(*) AS cnt 
    FROM product p 
    INNER JOIN category c 
     ON p.id_category = c.id_category 
    GROUP BY p.id_category 
) 
WHERE cnt = (SELECT MAX(cnt) FROM (
       SELECT p.id_category, COUNT(*) AS cnt 
       FROM product p 
       INNER JOIN category c 
        ON p.id_category = c.id_category 
       GROUP BY p.id_category 
      )); 

此查询甚至会在MySQL运行。正如你所看到的,查询很丑陋,这就是为什么诸如CTE和分析函数被引入ANSI标准的原因之一。

+0

这也是一个很好的答案。但它不是ANSI,对吧?我想知道一种只使用子查询或另一种ansi方式的方法。谢谢 – OnScreen

+0

@OnScreen让我删除CTE。 –

+0

这真的起作用我正在想这样的事情。我认为这确实是仅使用子查询的最佳解决方案。我测试了带领带的顶部,这个具有相同的性能。 50%。谢啦!!! – OnScreen