1

これらのビューを作成するには、おそらくもっと良い方法があります。私は SQL の経験が限られているため、これが私が設計した方法です。SQL の達人が私をより効率的な方向に向けてくれることを願っています。

私のビューには基本的に 3 つのテーブル (場合によっては 4 つ) があります。ここに重要な構造があります。

Table USER
USER_ID | EMAIL | PASSWORD | CREATED_DATE

(インデックス: USER_ID)

Table USER_META
ID | USER_ID | NAME | VALUE

(インデックス: ID、USER_ID、NAME)

Table USER_SCORES
ID | USER_ID | GAME_ID | SCORE | CREATED_DATE

(インデックス: ID、USER_ID)

すべてのテーブルは、最初の ID 列を自動インクリメント主キーとして使用します。

2 番目のテーブル「USER_META」は、すべての連絡先情報やその他の情報を保持する場所です。主に、first_name、last_name、street、city などです。 - ユーザーによっては、4 項目または 140 項目になる可能性があるため、USER テーブルに 150 列ではなく、このテーブルを使用します。

レポート、検索、および編集には、USER_META から約 20 個の値が必要なので、次のようなビューがあります。

View V_USR_META
select USER_ID,EMAIL,
(select VALUE from USER_META 
   where NAME = 'FIRST_NAME' and USER_ID = u.USER_ID) as first_name,
(select VALUE from USER_META 
   where NAME = 'LAST_NAME'  and USER_ID = u.USER_ID) as last_name,
(select VALUE from USER_META 
   where NAME = 'CITY'  and USER_ID = u.USER_ID) as city,
(select VALUE from USER_META 
   where NAME = 'STATE'  and USER_ID = u.USER_ID) as state,
(select VALUE from USER_META 
   where NAME = 'ZIP'  and USER_ID = u.USER_ID) as zip,
    /* 10 more selects for different meta values here */
(select max(SCORE) from USER_SCORES 
   where USER_ID = u.USER_ID) as high_score,
(select top (1) CREATED_DATE from USER_SCORES 
   where USER_ID = u.USER_ID 
   order by id desc) as last_game
from USER u

この取得はかなり遅く、実際にはもっと多くのサブクエリがあります。これはクエリを説明するためのものです。また、その他のテーブルをいくつか取得するためにクエリを実行する必要があります。ユーザーに関する情報。

ユーザーを検索するとき、名前、ユーザー ID、電子メール、スコアなどを検索するときにビューを使用します。また、すべてのデータを 1 か所に表示するときに、ユーザー情報画面に入力するためにも使用します。

だから - ビューを書くためのより良い方法はありますか?

4

2 に答える 2

1

これらすべての相関サブクエリの代わりに、maxwithを使用することもできますcase:

select u.USER_ID,
       u.EMAIL,
       max(case when um.name = 'FIRST_NAME' then um.value end) first_name,
       max(case when um.name = 'LAST_NAME' then um.value end) last_name
       ...
from USER u
       left join USER_META um 
                on u.user_id = um.user_id
group by u.user_id, u.email

user_scores次に、結果を追加できます。

select u.USER_ID,
       u.EMAIL,
       max(case when um.name = 'FIRST_NAME' then um.value end) first_name,
       max(case when um.name = 'LAST_NAME' then um.value end) last_name
       ...,
       max(us.score) maxscore,
       max(us.created_date) maxcreateddate
from USER u
       left join USER_META um 
                on u.user_id = um.user_id
       left join USER_SCORES us
                on u.user_id = us.user_id
group by u.user_id, u.email
于 2013-10-29T04:58:59.393 に答える
0
WITH Meta AS (
    SELECT USER_ID
          ,FIRST_NAME
          ,LAST_NAME
          ,CITY
          ,STATE
          ,ZIP
    FROM USER_META
    PIVOT (
        MAX(VALUE) FOR NAME IN (FIRST_NAME, LAST_NAME, CITY, STATE, ZIP)
    ) AS p
)
,MaxScores AS (
    SELECT USER_ID
          ,MAX(SCORE) AS Score
    FROM USER_SCORES
    GROUP BY USER_ID
)
,LastGames AS (
    SELECT USER_ID
          ,MAX(CREATED_DATE) AS GameDate
    FROM USER_SCORES
    GROUP BY USER_ID
)
SELECT USER.USER_ID
      ,USER.EMAIL
      ,Meta.FIRST_NAME
      ,Meta.LAST_NAME
      ,Meta.CITY
      ,Meta.STATE
      ,Meta.ZIP
      ,MaxScores.Score
      ,LastGames.GameDate
FROM USER
     INNER JOIN Meta
         ON USER.USER_ID = Meta.USER_ID
     LEFT JOIN MaxScores
         ON USER.USER_ID = MaxScores.USER_ID
     LEFT JOIN LastGames
         ON USER.USER_ID = LastGames.USER_ID
于 2013-10-29T07:57:21.057 に答える