1

これを手伝ってくれる人に前もって感謝します。私はこれが以前にあまり痛みを伴わずに行われたのを見たことがあることを知っていますが、解決策を見つけることができないようです

私のデータベースは次のようになります。

`tbl_user:
----------
id         ( pkey )
email
fName
lName

tbl_userSparseType:
-------------------
id         ( pkey )
varName
displayName

tbl_userSparse:
---------------
id         ( pkey )
value      ( Value of Sparse Type )
user_id    ( => tbl_user.id )
userSparseType_id     ( => tbl_userSparseType.id )

サンプルデータを使用:

tbl_user:
(id,   email,              fName,   lName)
 1     Bob@example.com     Billy    Bob
 2     Betty@example.com   Betty    Sue
 3     Beam@example.com    Jim      Beam

tbl_userSparseType:
(id,   varName,    displayName)
 1     fullName    Full Name
 2     dayPhone    Day Phone
 3     nightPhone  Night Phone
 4     cellPhone   Cell Phone
 5     homeAddr    Home Address

tbl_userSparse:
(id,    value,             user_id,    userSparseType_id)
 1      Billy John Bob     1           1
 2      James B. Beam      3           1
 3      123-234-3456       1           2
 4      234-345-4567       1           4
 5      24 Best st.        2           5
 6      456-567-6789       3           3

2 つの左結合を実行しようとしましたが、これにより、次のようなスパース エントリごとに tbl_user 行が得られました。

(id, email,            fName,  lName, displayName, value)
 1,"Bob@example.com","Billy","Bob","Full Name","Billy John Bob"
 1,"Bob@example.com","Billy","Bob","Day Phone","123-234-3456"
 1,"Bob@example.com","Billy","Bob","Cell Phone","234-345-4567"

そして、45分程度の数回のセッションにもかかわらず、列に明示的に名前を付けずに次のようなものを取得する方法を見つけることができません.tbl_user行のサブセットに適用されるすべての表示名のみを動的に取得する方法が必要です.照会:

WHERE tbl_user.id IN (1,2)

 id | email             | fName | lName | Full Name,     | Day Phone    | Cell Phone   | 
Home Address
-------------------------------------------------------------------------------------------------------
 1  | Bob@example.com   | Billy | Bob   | Billy John Bob | 123-234-3456 | 234-345-4567 |
 2  | Betty@example.com | Betty | Sue   |                |              |              | 24 Best St.

事前にもう一度感謝します。これが大騒ぎせずにできることを願っています。:\

4

1 に答える 1

2

残念ながら、MySQLPIVOTには基本的に実行しようとしている機能がありません。CASEしたがって、ステートメントで集計関数を使用する必要があります。列数がわかっている場合は、値をハードコーディングできます。

select u.id, 
  u.email,
  u.fname,
  u.lname,
  max(case when t.displayname = 'Full Name' then us.value end) FullName,
  max(case when t.displayname = 'Day Phone' then us.value end) DayPhone,
  max(case when t.displayname = 'Cell Phone' then us.value end) CellPhone,
  max(case when t.displayname = 'Home Address' then us.value end) HOmeAddress
from tbl_user u
left join tbl_userSparse us
  on u.id = us.user_id
left join tbl_userSparseType t
  on us.userSparseType_id = t.id
where u.id in (1, 2) 
group by u.id, u.email, u.fname,u.lname;

デモで SQL Fiddleを参照してください

これを動的に実行する場合、つまり転置する列が事前にわからない場合は、次の記事を確認する必要があります。

動的ピボット テーブル (行を列に変換)

コードは次のようになります。

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'max(case when t.displayname = ''',
      t.displayname,
      ''' then us.value end) AS ',
      replace(t.displayname, ' ', '')
    )
  ) INTO @sql
FROM tbl_userSparse us
left join tbl_userSparseType t
  on us.userSparseType_id = t.id;

SET @sql = CONCAT('SELECT u.id, u.email, u.fname, u.lname, ', @sql, ' 
                  from tbl_user u
                  left join tbl_userSparse us
                    on u.id = us.user_id
                  left join tbl_userSparseType t
                    on us.userSparseType_id = t.id
                  where u.id in (1, 2) 
                  group by u.id, u.email, u.fname, u.lname');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

デモで SQL Fiddle を参照してください

于 2012-10-10T01:54:38.930 に答える