2017-02-24 14 views
1

私は今多くの試みがありましたが、本当に役立つものはありません。 私は柔軟なビューを作成することはできません(可能な場合)。 2つのタブの結果。ここ は私がwanntものです:Mysql SQLクエリから柔軟なビューを作成

表ビジター:

id vID First Name Last Name  Company  E-Mail    Phone Salutation Type      
1 1  Hans  Wurst  WDHUWDHUGMBGH [email protected] 123123  Mr   qwes  

ID  Hash    created 
1 sadasdasdasd 2017-02-24 08:31:37 
2 123kipdösas3 2017-02-24 08:31:37 
3 12oaskdasdap 2017-02-24 08:31:37 
4 asdauihsuahs 2017-02-24 08:31:37 

表VisitorData私は私のテーブル(ビュー)をwannt最後に

id vID type   value      created 
1 1 First Name  Hans    2017-02-24 09:15:11 
2 1 Last Name  Wurst    2017-02-24 09:15:11 
3 1 Company   WDHUWDHUGMBGH  2017-02-24 09:15:11 
4 1 E-Mail   [email protected]  2017-02-24 09:15:11 
5 1 Phone   123123    2017-02-24 09:15:11 
6 1 Salutation  Mr     2017-02-24 09:15:11 
7 1 Type   qwes    2017-02-24 09:15:11 

ようになり

実際には、VisitorData.typeに何があるのか​​わかりません。 だから、僕は

CREATE VIEW DataVisitorView AS 
    SELECT DataVisitor.id, DataVisitor.hash, 
    IF(DataVisitorValues.Type='First Name',DataVisitorValues.Value,null) AS First Name, 
    IF(DataVisitorValues.Type='Last Name',DataVisitorValues.Value,null) AS Last Name , 
    IF(DataVisitorValues.Type=' Company ',DataVisitorValues.Value,null) AS Company   , 
    IF(DataVisitorValues.Type='E-Mail',DataVisitorValues.Value,null) AS E-Mail, 
    IF(DataVisitorValues.Type='Phone   ',DataVisitorValues.Value,null) AS Phone   , 
    IF(DataVisitorValues.Type='Salutation  ',DataVisitorValues.Value,null) AS Salutation  
FROM `DataVisitor` 
    LEFT JOIN `DataVisitorValues` 
     ON `DataVisitor`.`id` = `DataVisitorValues`.`vID` 

ので、私はこの

CREATE VIEW `DataVisitorView` AS 
SELECT 
    DataVisitorValues2.typ 
FROM (`DataVisitor2` 
    LEFT JOIN `DataVisitorValues2` 
    ON `DataVisitor2`.`id` = `DataVisitorValues2`.`vID`) 
Where `DataVisitor2`.`id` = `DataVisitorValues2`.`vID` 

についてもっと考えていたんカントが、それはば完全に間違っている私は

|typ| 

First Name 
Last Name 
Company 
... 

でテーブルを取得し、これは、このための任意の解決策があります? 私は仕事のためにPhpを使用しましたが、テーブルは自動的に更新され、文字列ジョブは何も役に立ちません

+0

列のリストを作成するには、列VisitorData.typeに何が含まれているかを知る必要があります。ビューが必要な場合は、ビューを作成する時点で固定されます。ビューではなく、プロシージャを使用して結果セットを作成することができます。 –

+0

訪問者ごとにvisitordataの行数が異なる可能性があり、type列のテキストは自由形式ですか? –

+0

@ p.Salmon新しいフォームが追加され、「新しい」タイプの名前を持つ場合、テーブル訪問者のデータは20以上のフォームの値を取得しますが、クエリを動的にする必要がないので、毎回SQLクエリを変更する必要はありません。 –

答えて

1

変数を含む動的ビューまたはビューを作成することはできません。 動的クエリを行う必要があります。

何をしたいテーブル/挿入データ

CREATE TABLE Visitor 
    (`ID` INT, `Hash` VARCHAR(12), `created` VARCHAR(19)) 
; 

INSERT INTO Visitor 
    (`ID`, `Hash`, `created`) 
VALUES 
    (1, 'sadasdasdasd', '2017-02-24 08:31:37'), 
    (2, '123kipdösas3', '2017-02-24 08:31:37'), 
    (3, '12oaskdasdap', '2017-02-24 08:31:37'), 
    (4, 'asdauihsuahs', '2017-02-24 08:31:37') 
; 


CREATE TABLE VisitorData 
    (`id` INT, `vID` INT, `type` VARCHAR(10), `value` VARCHAR(15), `created` VARCHAR(19)) 
; 

INSERT INTO VisitorData 
    (`id`, `vID`, `type`, `value`, `created`) 
VALUES 
    (1, 1, 'First Name', 'Hans', '2017-02-24 09:15:11'), 
    (2, 1, 'Last Name', 'Wurst', '2017-02-24 09:15:11'), 
    (3, 1, 'Company', 'WDHUWDHUGMBGH', '2017-02-24 09:15:11'), 
    (4, 1, 'E-Mail', '[email protected]', '2017-02-24 09:15:11'), 
    (5, 1, 'Phone', '123123', '2017-02-24 09:15:11'), 
    (6, 1, 'Salutation', 'Mr', '2017-02-24 09:15:11'), 
    (7, 1, 'Type', 'qwes', '2017-02-24 09:15:11') 
; 

クエリ

を作成し、出力のthatsは、ピボットテーブルと呼ばれています。 これは、GROUP BYを使用して、このような関数MAXを使用して行われます。

id  vid First_name Last_Name Company  E-Mail   Phone Salutation Type  
------ ------ ---------- --------- ------------- --------------- ------ ---------- -------- 
    1  1 Hans  Wurst  WDHUWDHUGMBGH [email protected] 123123 Mr   qwes  

SELECT 
    Visitor.id 
, VisitorData.vid 
, MAX(CASE WHEN VisitorData.type = 'First Name' THEN VisitorData.value ELSE NULL END) AS 'First_name' 
, MAX(CASE WHEN VisitorData.type = 'Last Name' THEN VisitorData.value ELSE NULL END) AS 'Last_Name' 
, MAX(CASE WHEN VisitorData.type = 'Company' THEN VisitorData.value ELSE NULL END) AS 'Company' 
, MAX(CASE WHEN VisitorData.type = 'E-Mail' THEN VisitorData.value ELSE NULL END) AS 'E-Mail' 
, MAX(CASE WHEN VisitorData.type = 'Phone' THEN VisitorData.value ELSE NULL END) AS 'Phone' 
, MAX(CASE WHEN VisitorData.type = 'Salutation' THEN VisitorData.value ELSE NULL END) AS 'Salutation' 
, MAX(CASE WHEN VisitorData.type = 'Type' THEN VisitorData.value ELSE NULL END) AS 'Type' 
FROM 
Visitor 
INNER JOIN 
VisitorData 
ON 
Visitor.id = VisitorData.vid 
GROUP BY 
    Visitor.id 
, VisitorData.vid 
ORDER BY 
    Visitor.id 
, VisitorData.vid 

結果は、あなたがこれを使用することができ、列を動的にするには。

SET SESSION group_concat_max_len = 1000000 -- enlarge GROUP_CONCAT output to 10 Mb 
SET @group_concat_sql = NULL; 

# generate all MAX lines 
SELECT 
    GROUP_CONCAT(DISTINCT 
    CONCAT(
     'MAX(CASE WHEN VisitorData.type = \'',VisitorData.type,'\' THEN VisitorData.value ELSE NULL END) AS \'',VisitorData.type,'\''  
    ) 
) 
    INTO @group_concat_sql 
FROM 
VisitorData; 

# generate complete SQL query 
SET @sql = 
CONCAT(
'SELECT 
    Visitor.id 
    , VisitorData.vid 
' 
, ',' 
, @group_concat_sql 
, 'FROM 
Visitor 
INNER JOIN 
VisitorData 
ON 
Visitor.id = VisitorData.vid 
GROUP BY 
    Visitor.id 
, VisitorData.vid 
ORDER BY 
    Visitor.id 
, VisitorData.vid 
' 
); 

# execute SQL query 
PREPARE stmt FROM @sql; 
EXECUTE stmt; 
DEALLOCATE PREPARE stmt; 

結果

id  vid First Name Last Name Company  E-Mail   Phone Salutation Type  
------ ------ ---------- --------- ------------- --------------- ------ ---------- -------- 
    1  1 Hans  Wurst  WDHUWDHUGMBGH [email protected] 123123 Mr   qwes  
+0

タイのタイプに、100種類の可能なタイプ+デペンデントがありますが、私はまだもっとダイナミックなバージョンを楽しみにしています。あなたのコードは素晴らしいですし、おそらく誰かに役立つことを願っています –

1

、あなたのデータを制御の多くを持っているつもりされていないかのように見えます。私は@ Raymond Nijlandのアプローチにかなり同意しますが、ある程度の制御を加えるためにいくつかのコードを追加します。 まず、同義語表を作成します。

drop table if exists synonym_table; 
create table synonym_table (ordinalposition int, `type` varchar(10) , synonym varchar(10)); 
alter table synonym_table 
    add key k001(`type`), 
    add key k002(synonym); 

これは、あなたが会社やCOなどの用語を標準化することができます。例えば

truncate table visitordata; 
INSERT INTO VisitorData 
    (`id`, `vID`, `type`, `value`, `created`) 
VALUES 
    (1, 1, 'First Name', 'Hans', '2017-02-24 09:15:11'), 
    (2, 1, 'Last Name', 'Wurst', '2017-02-24 09:15:11'), 
    (3, 1, 'Company', 'WDHUWDHUGMBGH', '2017-02-24 09:15:11'), 
    (4, 1, 'E-Mail', '[email protected]', '2017-02-24 09:15:11'), 
    (5, 1, 'Phone', '123123', '2017-02-24 09:15:11'), 
    (6, 1, 'Salutation', 'Mr', '2017-02-24 09:15:11'), 
    (7, 1, 'Type', 'qwes', '2017-02-24 09:15:11'), 
    (8, 2, 'FName', 'Hans', '2017-02-24 09:15:11'), 
    (9, 2, 'Last Name', 'Wurst', '2017-02-24 09:15:11'), 
    (10, 2, 'Co.', 'WDHUWDHUGMBGH', '2017-02-24 09:15:11') 

insert into synonym_table (`type`,synonym) 
select distinct `type`,`type` from visitordata v order by id 
on duplicate key update `type` = v.`type`; 

ノートタイプと重複するキー句の一意性 今すぐアップデート知ら同義語を保証する同義語のデフォルト - あなたが必要なだけこの操作を行う必要があります注意してください

update synonym_table 
     set synonym = 'First Name' where `type` in('fname' , 'FirstName'); 

update synonym_table 
    set synonym = 'Company' where `type` in('Co.' , 'Business', 'Agency'); 

MariaDB [sandbox]> select * from synonym_table; 
+--------------+------------+------------+ 
| ordinalvalue | type  | synonym | 
+--------------+------------+------------+ 
|   NULL | First Name | First Name | 
|   NULL | Last Name | Last Name | 
|   NULL | Company | Company | 
|   NULL | E-Mail  | E-Mail  | 
|   NULL | Phone  | Phone  | 
|   NULL | Salutation | Salutation | 
|   NULL | Type  | Type  | 
|   NULL | FName  | First Name | 
|   NULL | Co.  | Company | 
+--------------+------------+------------+ 

更新列ヘッダーの順序を制御する順序。 raymondからsynonym_tableを使用するようにコードを変更してください。

関連する問題