2017-02-24 47 views
1

我現在做了很多嘗試,但沒有任何實際的幫助。 我想創建一個靈活的視圖(如果可能)。有2個表格的結果。 這裏是我wannt:Mysql從SQL查詢創建靈活視圖

表參觀者:

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

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 

最後我wannt我的表(視圖)是這樣的:

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

事實是,我們不知道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的工作,但表中,但自動更新自己和一個chrone作業是沒有什麼幫助在這裏

+0

要創建列列表,您需要知道VisitorData.type列中可能存在的內容,或者您​​必須動態創建列表。如果你想要一個視圖,它將在你創建它時被修復。您可以使用過程來即時創建結果集,而不是視圖。 –

+0

因此,visitordata中的行數對於每個訪問者可能會不同,並且type列中的文本是自由格式? –

+0

@ p.Salmon表訪問者數據獲取20+表單的值,如果新表單將被添加,並有「新」類型的名稱,我希望查詢是動態的,所以我不必每次都改變sql查詢。 –

回答

1

你不能創建動態視圖或與變量的意見。 所以你需要動態查詢。

CREATE TABLE /插入數據

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') 
; 

查詢

你想要的是一個輸出這就是被稱爲透視表。 這是通過GROUP BY和使用MAX這樣的函數完成的。

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 

結果

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

爲了使列動態,你可以用這個。

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

ty的類型,以便與我分享您的時間,但我仍然期待更加動態的版本。你的代碼真棒,我希望它可以幫助別人 –

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