2017-11-04 41 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