2017-12-13 20 views
4

は、私はこのような表が持っているどのようにSQL Server内のグループ同様の行に

CREATE TABLE MyTable ([Date] date, 
         ConfigID int, 
         ItemID int, 
         ClientName char(1), 
         Metric1 decimal(3,1), 
         Metric2 decimal(3,1)); 
INSERT INTO MyTable 
VALUES ('2017-01-01',1,1,'A',2.0,2.0), 
     ('2017-01-01',3,1,'A',2.0,2.0), 
     ('2017-01-01',4,2,'B',5.0,5.0), 
     ('2017-01-02',4,3,'A',6.0,6.0), 
     ('2017-01-01',2,1,'A',2.0,2.0);  

WITH Dupes   
AS (   
    SELECT *   
     ,ROW_NUMBER() OVER ( 
      PARTITION BY 
       [Date] 
       ,[ItemID] 
       ,[ClientName] 
       ,[Metric1] 
       ,[Metric2] 
      ORDER BY [Date] DESC 
    ) AS RowNum 
    FROM myTable) 

SELECT * 
FROM Dupes 

しかし、それはこのような何かを返す:

Date  ConfigID ItemID ClientName Metric1 Metric2 RowNum 
====  ======== ====== ========== ======= ======= ====== 
2017-01-01 1   1   A    2.0  2.0  1 
2017-01-01 3   1   A    2.0  2.0  2 
2017-01-01 4   2   B    5.0  5.0  1 
2017-01-02 4   3   A    6.0  6.0  1 
2017-01-01 2   1   A    2.0  2.0  3 
.... 
(20 million rows here) 
0を

PARTITION BY句に基づいて同様の項目をグループ化したいと思います。言い換えれば、私は(私は本当にRowNumを必要としない)、このようなものを見てみたいと思います:

Date  ConfigID ItemID ClientName Metric1 Metric2 RowNum 
====  ======== ====== ========== ======= ======= ====== 
2017-01-01 1   1   A    2.0  2.0  1 
2017-01-01 3   1   A    2.0  2.0  2 
2017-01-01 2   1   A    2.0  2.0  3 
2017-01-01 4   2   B    5.0  5.0  1 
2017-01-02 4   3   A    6.0  6.0  1 
.... 
(20 million rows here) 

何SQLクエリは、グループにテーブル内の類似した/重複行を私を助けるでしょうか?進んでいただきありがとうございます。

+0

「グループ化」するとどういう意味ですか?あなたのデータセットにそれらを戻したくないですか?それらを集める?他に何か? – Larnu

+0

@ Larnu、私はそれらを手動で見直して、物事が違うところを見たいと思っていました(例えば、他の列にいくつの異なるConfigIDが同じ値を持っているか分かります)。 – user1330974

答えて

1

ROW_NUMBERの代わりにDENSE_RANKを使用すると役立ちますか?

;   
WITH Dupes   
AS (   
    SELECT *   
     ,DENSE_RANK () 
     OVER ( 
      ORDER BY 
       [Date] 
       ,[ItemID] 
       ,[ClientName] 
       ,[Metric1] 
       ,[Metric2]   
      DESC 
    ) AS GroupID 
    FROM myTable) 

SELECT * 
FROM Dupes 

がここに解決策が提案されている:

;   
WITH D1   
AS (   
    SELECT *   
     ,DENSE_RANK () 
     OVER ( 
      ORDER BY 
       [Date] 
       ,[ItemID] 
       ,[ClientName] 
       ,[Metric1] 
       ,[Metric2]   
      DESC 
    ) AS GroupID 
    FROM myTable) 
, Dupes AS (
    SELECT * 
     , COUNT(*) OVER (PARTITION BY GroupID) AS GroupItemsCount 
    FROM D1 
) 
SELECT * 
FROM Dupes 
WHERE GroupItemsCount <> 1 

をより良い方法がコメントでルカの提案に基づいて

;   
WITH Dupes   
AS (   
    SELECT *   
     ,COUNT(*) 
     OVER ( 
      partition BY 
       [Date] 
       ,[ItemID] 
       ,[ClientName] 
       ,[Metric1] 
       ,[Metric2]   
    ) AS GroupItemsCount 
    FROM myTable) 

SELECT * 
FROM Dupes 
WHERE GroupItemsCount > 1 
+0

はい! 'DENSE_RANK'は私が望むものに近いです。しかし、上記のクエリから与えられたランクの**複数の行**を持つデータをどのように抽出するのですか?たとえば、3つの行のランクが「1」で、残りの行には一意のランクが割り当てられているとします(2 ... n)。次に、ランク '1'のものを抽出/レビューしたいだけです。どのような追加クエリがここで役立つでしょうか?ありがとうございました! – user1330974

+1

私は自分のPCの背後にいるわけではありませんが、別のCTEでGroupItemsCountとしてCOUNT()OVER(PARTITION BY GroupID)を試して、GroupItemsCount> 1 – Ezin82

+0

YESを試してみることをおすすめします。 'COUNT(*)OVER(PARTITION BY ....)'と 'count> 1'に基づいてフィルタリングし、' PARTITION BY'節の中のすべての基準による順序付けが機能します!どうもありがとうございました! – user1330974

1

ちょうど私はあなただけorder byが必要だと思う選択

;   
WITH Dupes   
AS (   
    SELECT *   
     ,ROW_NUMBER() OVER ( 
      PARTITION BY 
       [Date] 
       ,[ItemID] 
       ,[ClientName] 
       ,[Metric1] 
       ,[Metric2] 
      ORDER BY [Date] DESC 
    ) AS RowNum 
    FROM myTable) 

SELECT * 
FROM Dupes 
order by [Date] 
       ,[ItemID] 
       ,[ClientName] 
       ,[Metric1] 
       ,[Metric2], 
RowNum 
1

内で順序を与えます。 CTEは必要ありません。

. . . 
SELECT * 
FROM Dupes 
ORDER BY [Date], [ItemID], [ClientName], [Metric1], [Metric2]; 
1

可能性があり、COUNT(*) PARTITION BY(...)を使用して動作するようです:

CREATE TABLE MyTable ([Date] date, 
         ConfigID int, 
         ItemID int, 
         ClientName char(1), 
         Metric1 decimal(3,1), 
         Metric2 decimal(3,1)); 
INSERT INTO MyTable 
VALUES ('2017-01-01',1,1,'A',2.0,2.0), 
     ('2017-01-01',3,1,'A',2.0,2.0), 
     ('2017-01-01',4,2,'B',5.0,5.0), 
     ('2017-01-02',4,3,'A',6.0,6.0), 
     ('2017-01-01',2,1,'A',2.0,2.0);  

WITH Dupes   
AS (   
    SELECT *   
     ,COUNT(*) OVER ( 
      PARTITION BY 
       [Date] 
       ,[ItemID] 
       ,[ClientName] 
       ,[Metric1] 
       ,[Metric2] 
      ORDER BY [Date] DESC 
    ) AS DupeCount 
    FROM myTable) 

SELECT * 
FROM Dupes 
WHERE DupeCount > 1 
+0

合意、@ Forty3。できます。答えを書き留めてくれてありがとう。二重引用符を簡単に確認できるように、WHERE DupeCount> 1の後にORDER BY [日付]、[ItemID]、[ClientName]、[Metric1]、[Metric2]を追加しました。 :) – user1330974

関連する問題