[英]Mysql Create Flexible View from SQL query
I had a lot of attempts now but nothing realy helps. 我现在做了很多尝试,但没有任何帮助。 I wannt to create a flexible View(if possible).
我希望创建一个灵活的View(如果可能)。 With the result of 2 tabels.
结果为2个表格。 Here is what i wannt :
这是我想要的:
Table Visitor: 表访客:
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
Table VisitorData 表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 asddas@asdsd.de 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
In the end i wannt my Table(view) to be like: 最后,我希望我的表(视图)像:
id vID First Name Last Name Company E-Mail Phone Salutation Type
1 1 Hans Wurst WDHUWDHUGMBGH asddas@asdsd.de 123123 Mr qwes
the fact is that we dont know what can be in the VisitorData.type. 事实是,我们不知道VisitorData.type中可以包含什么。 so i cant just do
所以我不能做
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`
so i was thinking more about this 所以我在想更多
CREATE VIEW `DataVisitorView` AS
SELECT
DataVisitorValues2.typ
FROM (`DataVisitor2`
LEFT JOIN `DataVisitorValues2`
ON `DataVisitor2`.`id` = `DataVisitorValues2`.`vID`)
Where `DataVisitor2`.`id` = `DataVisitorValues2`.`vID`
but this it totaly wrong i get a table with 但这完全是错误的我得到一张桌子
|typ|
First Name
Last Name
Company
...
Is there any Solution for this? 有什么解决办法吗? I also used Php for the job but the table but automaticly update himself and a chrone job is nothing that helps here
我也用Php做这份工作,但是桌子却自动更新了,而chrone的工作对这里没有帮助
You cant create dynamic views or views with variables in it. 您无法创建动态视图或其中包含变量的视图。 So you need to dynamic query.
因此您需要动态查询。
Create table/insert data 创建表/插入数据
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', 'asddas@asdsd.de', '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')
;
Query 询问
What you want is a output thats is called a pivot table. 您想要的是一个称为数据透视表的输出。 This is done with GROUP BY and using the function MAX like this.
这是通过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
Result 结果
id vid First_name Last_Name Company E-Mail Phone Salutation Type
------ ------ ---------- --------- ------------- --------------- ------ ---------- --------
1 1 Hans Wurst WDHUWDHUGMBGH asddas@asdsd.de 123123 Mr qwes
To make the columns dynamic you can use this. 要使列动态化,您可以使用它。
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;
Result 结果
id vid First Name Last Name Company E-Mail Phone Salutation Type
------ ------ ---------- --------- ------------- --------------- ------ ---------- --------
1 1 Hans Wurst WDHUWDHUGMBGH asddas@asdsd.de 123123 Mr qwes
It looks as though you aren't going to have a lot of control over your data. 看来您对数据没有太多控制权。 I pretty much agree with @Raymond Nijland approach but I would add some code to bring a degree of control.
我非常同意@Raymond Nijland的方法,但是我会添加一些代码来带来一定程度的控制。 Start by creating a synonyms table.
首先创建同义词表。
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);
This will allow you to standardise terms like Company and CO. For example 这将使您能够标准化公司和公司等术语。例如
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', 'asddas@asdsd.de', '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`;
Note the synonyms default to the type and the on duplicate key clause ensures uniqueness Now update known synonyms - note you will have to do this as often as necessary 请注意,同义词默认为类型,并且onplicate key子句可确保唯一性现在更新已知的同义词-请注意,您将必须根据需要经常执行此操作
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 |
+--------------+------------+------------+
Update the ordinalposition to control the order of the column headers. 更新ordinalposition以控制列标题的顺序。 Now adapt the code from raymond to use the synonym_table
现在修改雷蒙德的代码以使用synonym_table
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.