簡體   English   中英

從分組依據中排除列

[英]Exclude Column From Group By

我有一個耗材表,其中列出了不同供應商的商品價格:

| ID | Item | Price | Supplier |

ID是主鍵(只是一個自動生成的整數)。 項目是產品的名稱。 價格是產品的價格。 供應商是外鍵(整數)。

我想列出每個項目的最便宜的價格和供應商。

我對數據庫比較陌生,到目前為止,我已經做到了:

SELECT Name, MIN(Price), Supplier FROM Supplies GROUP BY Name

這當然給了我錯誤

供應商不在匯總功能或分組子句中。

我已經在Google上進行了一些搜索,並閱讀了許多有關該主題的文章和答案,但是它們似乎都比我復雜得多,並且使我感到困惑(如上所述,我對數據庫和SQL的經驗不足),或者他們只是在談論錯誤,而不是如何解決。

任何幫助,將不勝感激。 提前致謝。

根據您的RDBMS,您也許可以使用ROW_NUMBER()來為每條記錄分配一個排名,並從中優先選擇一個。 這比使用其他聯接或相關子查詢要快,但是例如,當前MySQL不支持。

WITH
    sorted_supplies AS
(

    SELECT
        supplies.*,
        ROW_NUMBER() OVER (PARTITION BY name ORDER BY price)   AS price_ordinal
    FROM
        supplies

)
SELECT
    *
FROM
    sorted_supplies
WHERE
    price_ordinal = 1
;

如果沒有對ROW_NUMBER()的支持,那么您將被帶走其他聚合和聯接的道路。

SELECT
    supplies.*
FROM
    supplies
INNER JOIN
(
    SELECT
        name,
        MIN(price)   AS min_price
    FROM
        supplies
    GROUP BY
        name
)
    AS min_prices
        ON  min_prices.name      = supplies.name
        AND min_prices.min_price = supplies.price

請注意,如果所有價格最低的供應商都將以相同的價格返回該查詢。

可以通過使用RANK()而不是ROW_NUMBER()來強制執行第一個查詢

在大多數數據庫中,可以使用ANSI標准窗口函數:

select s.*
from (select s.*, min(price) over (partition by item) as minprice
      from supplies
     ) s
where price = minprice;

您可以對結果進行排名,然后選擇最低/最高的排名項目(基於排序順序)。 假設您使用的是SQL Server 2008或更高版本:

SELECT
    Item, Price, Supplier
FROM (
    SELECT
        ROW_NUMBER() OVER (PARTITION BY Item ORDER BY Price ASC) PriceRank
        , Item
        , Price
        , Supplier
    FROM
        Supplies
    ) supplies_ranked
WHERE
    PriceRank = 1

問題的症結在於-如果您有多個供應商以完全相同(最低)的價格提供齒輪,該怎么辦? 那么應在結果集中返回哪個供應商?

完成您要執行的操作的方法是獲取最低價格,然后將外部聯接返回到product = product和price = price等的同一表。 但是請理解,如果您遇到上述情況,您將返回兩行-每一行都提供最低價格。

自從我開始編寫此代碼以來,這里彈出了3或4個新答案,因此我想猜測實際的代碼已經存在。 關於查詢為何無法按您預期的方式運行,我將在此處保留此文本作為“普通英語”的解釋。

如果沒有partition by (某些類似於SQL的環境,如Access),則也可以執行以下操作:

select s.name, s.supplier, s.price from
(select name, min(price) as min_price from supplies group by name) mp
join supplies s on mp.name=s.name and mp.min_price = s.price 

這不如partition by有效partition by因為它有一個子查詢來查詢每個名稱的最低價格。 請注意,如果出現平局,它將返回多個供應商; 您可能想要也可能不想要。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM