web-dev-qa-db-ja.com

複数行にわたるWHERE句、GROUP BY

次のテーブル構造があります

AccountID   Property            Value
123456      Status              Active
123456      City                Los Angeles
123456      RegistrationDate    2018-05-11 11:30:14.000
543210      Status              Active
543210      City                Las Vegas
543210      RegistrationDate    2018-05-11 11:13:14.000
888888      Status              Inactive
888888      City                Toronto
888888      RegistrationDate    2015-05-12 11:13:14.000 

Property == Status and Value == Active And Property == RegistrationDate and Value == 2018-05-11 11:30:14.000であるすべての行を選択できるようにしたい

なんらかのGROUP BYを実行してから、その集計を選択する必要があると考えていますが、頭がよくありません(私のSQLは本当に錆びています)。

上記の「クエリ」に対して次の出力が必要です

AccountID    Status    RegistrationDate
123456       Active    2018-05-11 11:30:14.000
543210       Active    2018-05-11 11:30:14.000

すべての列が同じ行に存在していた場合は、次のように記述します。

SELECT AccountID FROM Property
WHERE Status = 'Active'
AND RegistrationDate = '2018-05-11 11:30:14.000'
5
JOSEFtw

デザインパターンはEAV( entity-attribute-value )と呼ばれます。通常、どちらかが必要ですGROUP BYまたはこのデザインで複数の結合を使用したクエリ:

SELECT
      a.AccountID               
FROM 
      tbl AS a
      JOIN tbl AS b
      ON a.AccountID = b.AccountID
WHERE
      a.Property = 'Status' 
  AND a.Value    = 'Active'

  AND b.Property = 'RegistrationDate' 
  AND b.Value    = '2018-05-11 11:30:14.000' ;
10
ypercubeᵀᴹ

これを表現するもう1つの方法は、PIVOTを使用してEAV構造を表形式に変換することです。与えられた:

DROP TABLE IF EXISTS dbo.EAV;

CREATE TABLE dbo.EAV
(
    AccountID integer NOT NULL,
    Property varchar(30) NOT NULL,
    Value sql_variant NULL
);

INSERT dbo.EAV
    (AccountID, Property, [Value])
VALUES
    (123456, 'Status', CONVERT(sql_variant, 'Active')),
    (123456, 'City', CONVERT(sql_variant, 'Los Angeles')),
    (123456, 'RegistrationDate', CONVERT(sql_variant, CONVERT(datetime, '2018-05-11 11:30:14.000', 121))),
    (543210, 'Status', CONVERT(sql_variant, 'Active')),
    (543210, 'City', CONVERT(sql_variant, 'Las Vegas')),
    (543210, 'RegistrationDate', CONVERT(sql_variant, CONVERT(datetime, '2018-05-11 11:13:14.000', 121))),
    (888888, 'Status', CONVERT(sql_variant, 'Inactive')),
    (888888, 'City', CONVERT(sql_variant, 'Toronto')),
    (888888, 'RegistrationDate', CONVERT(sql_variant, CONVERT(datetime, '2015-05-12 11:13:14.000', 121)));

クエリの例は次のとおりです。

SELECT
    P.AccountID,
    P.[Status],
    P.City,
    P.RegistrationDate
FROM dbo.EAV AS E
PIVOT (MAX([Value]) 
    FOR Property IN 
    (
        [Status], 
        [City], 
        [RegistrationDate])
    ) AS P
WHERE 
    P.[Status] = CONVERT(sql_variant, 'Active')
    AND P.RegistrationDate = CONVERT(sql_variant, CONVERT(datetime, '2018-05-11 11:30:14.000', 121));

結果:

アカウントID |ステータス|市| RegistrationDate 
 --------:| :-- :---------- | :------------------ 
 123456 |アクティブ|ロサンゼルス| 2018年11月5日11:30:14 

db <> fiddle ---(ここ

6
Paul White 9