8

次のように、店舗、店舗内の部門、および各部門の売上のリストがあります (サブクエリで max(sales) を使用して作成されますが、ここではそれほど重要ではないと思います):

toronto    baskets 500
vancouver  baskets 350
halifax    baskets 100
toronto    noodles 275
vancouver  noodles 390
halifax    noodles 120
halifax    fish    200

各店舗で一番売れている売り場をお聞きしたいです。結果は次のようになります。

toronto    baskets 500
vancouver  noodles 275
halifax    fish    200

GROUP BY を使用すると、サブクエリからのすべてのリストが含まれます。一時テーブルなしでこれを行うためのきれいな方法はありますか?

4

7 に答える 7

4

これはSql Serverで機能します(確かに2000以降)

SELECT a.Store, a.Department, a.Sales
FROM temp a
INNER JOIN 
(SELECT store, max(sales) as sales
FROM temp
GROUP BY Store) b
ON a.Store = b.Store AND a.Sales = b.Sales;
于 2008-11-04T00:45:39.087 に答える
2

SQL2005の2つのソリューションは次のとおりです。私がこれまでに見た他のものは、2つの売上高が同じである場合、正しいデータを返さない可能性があります。しかし、それはあなたのニーズに依存します。

1つ目はRow_Number()関数を使用し、すべての行が売上の低いものから高いものへとランク付けされます(その後、いくつかのタイブレークルール)。次に、結果を得るために店舗ごとに最高ランクが選択されます。

Row_Number関数にPartionBy句を追加してみたり(BOLを参照)、「in」句の代わりに内部結合を使用して調査したりできます。

2つ目は、Turnkeyのアイデアを借りて、再びランク付けしますが、ストアごとに分割するため、最初にランク付けされたものを選択できます。Dense_Rankは、2つの同じ行に同じランクを与える可能性があるため、ストアと部門が一意でない場合は、2つの行を返す可能性があります。Row_numberを使用すると、番号はパーティション内で一意になります。

注意すべき点は、これは遅いかもしれませんが、他のソリューションの1つでのサブクエリよりも、ほとんどのデータセットで高速になるということです。このソリューションでは、クエリを1行に1回実行する必要があり(並べ替えなどを含む)、多くのクエリが発生する可能性があります。

他のクエリでは、店舗あたりの最大売上を選択してその方法でデータを返し、2つの部門の売上が同じである場合は、店舗の重複行を返します。最後のクエリはこれを示しています。

DECLARE @tbl as TABLE (store varchar(20), department varchar(20), sales int)

INSERT INTO @tbl VALUES ('Toronto', 'Baskets', 500)
INSERT INTO @tbl VALUES ('Toronto', 'Noodles', 500)
INSERT INTO @tbl VALUES ('Toronto', 'Fish', 300)
INSERT INTO @tbl VALUES ('Halifax', 'Fish', 300)
INSERT INTO @tbl VALUES ('Halifax', 'Baskets', 200)

-- Expect Toronto/Noodles/500 and Halifax/Fish/300

;WITH ranked AS -- Rank the rows by sales from 1 to x
(
    SELECT 
        ROW_NUMBER() OVER (ORDER BY sales, store, department) as 'rank', 
        store, department, sales
    FROM @tbl
)

SELECT store, department, sales
FROM ranked
WHERE rank in (
    SELECT max(rank) -- chose the highest ranked per store
    FROM ranked
    GROUP BY store
)

-- Another way
SELECT store, department, sales
FROM (
    SELECT 
        DENSE_RANK() OVER (PARTITION BY store ORDER BY sales desc, 
store desc, department desc) as 'rank',
        store, department, sales
    FROM @tbl
) tbl
WHERE rank = 1


-- This will bring back 2 rows for Toronto
select tbl.store, department, sales
from @tbl tbl
    join (
        select store, max(sales) as maxSales from @tbl group by store
    ) tempTable on tempTable.store = tbl.store 
           and tempTable.maxSales = tbl.sales
于 2008-11-04T12:44:09.197 に答える
2

これは Oracle で機能しますが、他の実装では分析関数の構文が異なる場合があります (またはまったくない場合があります)。

select store
     , max(department) keep(dense_rank last order by sales)
     , max(sales)
  from (
        ...query that generates your results...
       )
 group by store
于 2008-11-04T00:12:31.167 に答える
1

2005 年以降、これは SQL Server で機能します。

with data as
(select store, department, sales
from <your query>),
 maxsales as
(select store,  sales = max(sales)
from data
group by store)
select store, (select top 1 department from data where store = t.store and sales = t.sales order by [your criteria for ties]), sales
from maxsales m

同点の場合に 1 つの部門のみを表示することを想定しているため、上位 1 と [同点の基準] でそれらを区別します。

于 2008-11-04T00:42:21.650 に答える
0

これはうまくいきます

Select Store, Department, Sales
From yourTable A
Where Sales = (Select Max(Sales)
               From YourTable
               Where Store = A.Store)
于 2008-11-04T01:16:17.260 に答える
0

多分これはうまくいくかもしれません。まだ試していませんが、もっと良い解決策があるかもしれません...

select yourTable.store, dept, sales
from yourTable
join (
  select store, max(sales) as maxSales from yourTable group by store
) tempTable on tempTable.store = yourTable.store 
           and tempTable.maxSales = yourTable.sales
于 2008-11-04T00:42:39.967 に答える
0

これは、一時テーブルのない SQL Server で機能します。

SELECT Store, Department, Sales FROM
(SELECT Store, Department, Sales,
DENSE_RANK()  OVER (PARTITION BY Store
ORDER BY Sales DESC) AS Dense_Rank
FROM Sales) A WHERE Dense_Rank = 1

WHERE "Sales" = 元のクエリ

于 2008-11-04T01:13:06.817 に答える