次のテーブル構造があります
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'
デザインパターンは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' ;
これを表現するもう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 ---(ここ