2
CREATE TABLE 属性 (
    ID VARCHAR(40)、
    タイプ VARCHAR(16)、
    データ VARCHAR(2048)、
    PRIMARY KEY(id,タイプ)
);

これは、実行しようとしているクエリの一般的な形式です。一般的な考え方は、「オブジェクト」には一意の ID があり、JavaScript オブジェクトのようにキーと値のペアがあるというものです。

SELECT a1.id、a1.data、a2.data、a3.data、a4.data、a6.data
    FROM 属性 a1、属性 a2、属性 a3、属性 a4、属性 a5
    LEFT JOIN 属性 a6 ON (a6.id=a5.id AND a6.type = 'Foreign Id')
        WHERE a1.id=a2.id
            AND a1.id=a3.id
            AND a1.id=a4.id
            AND a1.id=a5.id
            AND a1.type = '名'
            AND a2.type = 'ミドルネーム'
            AND a3.type = '姓'
            AND a4.type = 'タイムスタンプ'
            AND a5.type = 'Count'
            AND a5.data = 'MY_ID'

このクエリ'Foreign Id'では、オプションの属性です。問題は、私が得ていることです

SELECT は MAX_JOIN_SIZE を超える行を調べます。WHERE を確認し、SELECT が問題ない場合は SET SQL_BIG_SELECTS=1 または SET MAX_JOIN_SIZE=# を使用します。

言われたとおりにできることはわかっていますが、警告は、このクエリがひどく非効率的であることを心配しています。クエリを作成するより良い方法はありますか?

4

2 に答える 2

5

主キー キーはであるID, Typeため、集計関数を使用してクエリが決定論的であることを確認し、クエリを 0 結合に減らします。

SELECT  a.ID,
        MAX(CASE WHEN a.type = 'First Name' THEN a.Data END) AS FirstName,
        MAX(CASE WHEN a.type = 'Last Name' THEN a.Data END) AS LastName,
        MAX(CASE WHEN a.type = 'Timestamp' THEN a.Data END) AS `Timestamp`,
        MAX(CASE WHEN a.type = 'Count' THEN a.Data END) AS `Count`,
        MAX(CASE WHEN a.type = 'MY_ID' THEN a.Data END) AS MY_ID,
        MAX(CASE WHEN a.Type = 'Foreign Id' THEN a.Data END) AS ForeignId
FROM    Attributes a
GROUP BY a.ID;

ただし、Entity-Attribute-Value モデルは SQL アンチパターンであり、上記のクエリを使用して行を列に変換するよりも、データを正規化して属性を列として格納する方がはるかに優れていることに注意してください。

編集

属性に基づいてフィルターを追加するには、次のHAVING句を使用します。

SELECT  a.ID,
        MAX(CASE WHEN a.type = 'First Name' THEN a.Data END) AS FirstName,
        MAX(CASE WHEN a.type = 'Last Name' THEN a.Data END) AS LastName,
        MAX(CASE WHEN a.type = 'Timestamp' THEN a.Data END) AS `Timestamp`,
        MAX(CASE WHEN a.type = 'Count' THEN a.Data END) AS `Count`,
        MAX(CASE WHEN a.type = 'MY_ID' THEN a.Data END) AS MY_ID,
        MAX(CASE WHEN a.Type = 'Foreign Id' THEN a.Data END) AS ForeignId
FROM    Attributes a
GROUP BY a.ID
HAVING MAX(CASE WHEN a.type = 'MY_ID' THEN a.Data END) = 1;
于 2013-07-18T18:31:47.897 に答える