2

次のようなテーブルがあります。

  ID               AMID           DESC                  value 
  -----------------------------------------------------------------
  100              type A         AMID type A             10
  101              type B         AMID type B             18
  102              type C         AMID type C             34
  101               null            null                   4
  102               null            null                  19
  103              type D         AMID type D              6   
  103              type E            null                  7 

テーブルには約600万行が含まれています。

今、私はこのような結果を得たいです

  ID               AMID           DESC                  value 
  -------------------------------------------------------------
  100              type A         AMID type A             10
  101              type B         AMID type B             18
  102              type C         AMID type C             34
  101              type B         AMID type B              4
  102              type C         AMID type C             19
  103              type D         AMID type D              6   
  103              type E            null                  7

両方の行のIDのAMIDが等しい場合、同じ値が表示されます。いずれかがnullの場合、AMIDが異なる場合は、そのままにしておきます。

助けてくれてありがとう。

乾杯、

ハリッシュ

4

3 に答える 3

2

あなたの要件を正しく理解している場合:

SELECT ID
,      COALESCE(AMID, (
           SELECT TOP 1 AMID FROM Table t2 WHERE t2.ID=ID AND t2.AMID IS NOT NULL
       ))AS AMID
,      DESC                  
,      value  
FROM Table

COALESCE(Transact-SQL)

于 2012-04-30T12:46:49.233 に答える
2

まず、適切な DDL とサンプル データを設定しましょう。

USE tempdb;
GO

CREATE TABLE dbo.AMID
(
  ID     INT, 
  AMID   VARCHAR(32), 
  [DESC] VARCHAR(32), 
  value  INT
);

INSERT dbo.AMID SELECT 100, 'type A', 'AMID type A', 10
      UNION ALL SELECT 101, 'type B', 'AMID type B', 18
      UNION ALL SELECT 102, 'type C', 'AMID type C', 34
      UNION ALL SELECT 101,  null   , null         , 4
      UNION ALL SELECT 102,  null   , null         , 19
      UNION ALL SELECT 103, 'type D', 'AMID type D', 6   
      UNION ALL SELECT 103, 'type E', null         , 7;

ORDER BY を使用せずに TOP を使用する代わりに、パーティション + オーダーを使用して NULL 行を設定するために使用する行を 1 つだけ選択できます。限られたサンプル データでは、任意の ID に対して最大 2 行しかありませんが、それ以上の行がある場合は、これが重要です (それ以外の場合、ORDER BY を使用しない TOP のように、任意の行をプルして更新を行います)。予想より少ない)。AMIDこれは列の値で並べ替えますが、これを変更IDして、テーブルの任意の基準を使用して一番上の行を選択することができます。

;WITH src AS 
(
  SELECT ID, AMID, [DESC]
  FROM dbo.AMID 
  WHERE AMID IS NULL AND [DESC] IS NULL
),
nv AS 
(
  SELECT ID, AMID, [DESC], rn = ROW_NUMBER() OVER
  (PARTITION BY ID ORDER BY AMID) -- change this ordering accordingly
  FROM dbo.AMID 
  WHERE AMID IS NOT NULL
)
UPDATE src
  SET AMID = nv.AMID, [DESC] = COALESCE(nv.[DESC], src.[DESC])
FROM src INNER JOIN nv
ON src.ID = nv.ID
WHERE nv.rn = 1;

SELECT ID, AMID, [DESC], Value FROM dbo.AMID;

結果:

ID   AMID    DESC         value
---  ------  -----------  -----
100  type A  AMID type A  10
101  type B  AMID type B  18
102  type C  AMID type C  34
101  type B  AMID type B  4
102  type C  AMID type C  19
103  type D  AMID type D  6
103  type E  NULL         7     

クリーンアップすることを忘れないでください:

DROP TABLE dbo.AMID;
GO

余談ですが、これDESCは列の恐ろしい名前です。これは T-SQL キーワードであるため、常にでエスケープする必要があり[double quotes]ます。

于 2012-05-22T16:09:39.520 に答える
1
select a1.ID,
ISNULL(a1.amid, a3.amid),
a1.[DESC],
a1.value
FROM amid a1
LEFT OUTER JOIN (select a2.id, amid = max(a2.amid)
    from amid a2
    where  a2.amid is not null
    group by a2.id) a3 on a3.id = a1.id

使用しているSQLのバージョンが質問から明確ではありませんが、上記はSQL2000以降で動作するはずです。

基本的に、派生テーブルのクエリを微調整して、好みの結果を得ることができます。

于 2012-04-30T12:57:41.853 に答える