2012-09-18 60 views
2

發行在多個連接表

我工作的一個內容管理系統的學習,我希望能夠創建多個的視圖連接的表使用MySQL GROUP_CONCAT或轉動。除了連接表格外,我還需要執行PIVOT或GROUP_CONCAT(或其他函數),以便從每個表中取多行並將它們用作視圖中的列。爲了幫助可視化,這裏是我的工作的簡化:

SETUP

結構:

DROP TABLE IF EXISTS `date`; 
CREATE TABLE `date` (
    `col_pkid` int(11) NOT NULL AUTO_INCREMENT, 
    `col_guid` varchar(100) NOT NULL DEFAULT '', 
    `col_entry` varchar(100) NOT NULL, 
    `col_inquiry_name` varchar(100) NOT NULL, 
    `col_value` int(11) DEFAULT NULL, 
    PRIMARY KEY (`col_pkid`) 
); 

DROP TABLE IF EXISTS `bigText`; 
CREATE TABLE `bigText` (
    `col_pkid` int(11) NOT NULL AUTO_INCREMENT, 
    `col_guid` varchar(100) NOT NULL DEFAULT '', 
    `col_entry` varchar(100) NOT NULL, 
    `col_inquiry_name` varchar(100) NOT NULL, 
    `col_value` text, 
    PRIMARY KEY (`col_pkid`) 
); 

DROP TABLE IF EXISTS `smallText`; 
CREATE TABLE `smallText` (
    `col_pkid` int(11) NOT NULL AUTO_INCREMENT, 
    `col_guid` varchar(100) NOT NULL, 
    `col_entry` varchar(100) NOT NULL, 
    `col_inquiry_name` varchar(100) NOT NULL, 
    `col_value` varchar(100) DEFAULT '', 
    PRIMARY KEY (`col_pkid`) 
); 

DATA:

INSERT INTO `date` (`col_pkid`, `col_guid`, `col_entry`, `col_inquiry_name`, `col_value`) 
VALUES 
    (1,'d2kih1ho5z','1','Semester',1294834220), 
    (2,'d2kih1j99y','2','Semester',1327077210); 

INSERT INTO `bigText` (`col_pkid`, `col_guid`, `col_entry`, `col_inquiry_name`, `col_value`) 
VALUES 
    (16,'d2kih1kxwh','1','Description','Lorem ipsum dolor sit amet...'), 
    (17,'d2kih1mhnn','2','Description','Consectetur adipiscing elit...'); 

INSERT INTO `smallText` (`col_pkid`, `col_guid`, `col_entry`, `col_inquiry_name`, `col_value`) 
VALUES 
    (1,'d2kih1njuj','1','Title','Addition and Subtraction'), 
    (2,'d2kih1ot0x','1','Course','Math'), 
    (16,'d2kj5osy71','1','Location','Building 7'), 
    (17,'d2kj5p0z8f','1','Teachers','John'), 
    (18,'d2kj5p5efi','1','Teachers','Jane'), 
    (19,'d2kj5p98xv','1','Teachers',''), 
    (20,'d2kj5pasi9','1','Teachers',''), 
    (21,'d2kj5pbqbg','1','Teachers',''), 
    (22,'d2kj5pdxdb','2','Title','Reading Mark Twain'), 
    (23,'d2kih198do','2','Course','Literature'), 
    (24,'d2kj5opcgo','2','Location','Building 4'), 
    (25,'d2hd00n5eb','2','Teachers','Billy'), 
    (26,'d2hea3jo74','2','Teachers','Bob'), 
    (27,'d2hec78m5e','2','Teachers',''), 
    (28,'d2hec7bnar','2','Teachers',''), 
    (29,'d2hec7cbrq','2','Teachers',''); 

一些失敗的嘗試

我能夠做加入表一起相當好以下幾點:

DROP VIEW IF EXISTS entries; 
CREATE VIEW entries AS 
SELECT 
    st.col_entry, 
    if(st.col_inquiry_name = 'Title', st.col_value, NULL) AS 'Title', 
    if(st.col_inquiry_name = 'Course', st.col_value, NULL) AS 'Course', 
    if(bt.col_inquiry_name = 'Description', bt.col_value, NULL) AS 'Description', 
    if(d.col_inquiry_name = 'Semester', d.col_value, NULL) AS 'Semester', 
    if(st.col_inquiry_name = 'Location', st.col_value, NULL) AS 'Location', 
    if(st.col_inquiry_name = 'Teachers', st.col_value, NULL) AS 'Teachers' 
FROM smallText st 
INNER JOIN bigText bt 
ON st.col_entry = bt.col_entry 
INNER JOIN date d 
ON bt.col_entry = d.col_entry 
GROUP BY col_entry; 

但在這裏我只獲得了從每個表的第一行的值。這就是爲什麼我嘗試引入GROUP_CONCAT雖然我還沒有與,要麼很成功:

DROP VIEW IF EXISTS entries; 
CREATE VIEW entries AS 
SELECT 
    st.col_entry, 
    GROUP_CONCAT(if(st.col_inquiry_name = 'Title', st.col_value, NULL)) AS 'Title', 
    GROUP_CONCAT(if(st.col_inquiry_name = 'Course', st.col_value, NULL)) AS 'Course', 
    GROUP_CONCAT(if(bt.col_inquiry_name = 'Description', bt.col_value, NULL)) AS 'Description', 
    GROUP_CONCAT(if(d.col_inquiry_name = 'Semester', d.col_value, NULL)) AS 'Semester', 
    GROUP_CONCAT(if(st.col_inquiry_name = 'Location', st.col_value, NULL)) AS 'Location', 
    GROUP_CONCAT(if(st.col_inquiry_name = 'Teachers', st.col_value, NULL)) AS 'Teachers' 
FROM smallText st 
INNER JOIN bigText bt 
ON st.col_entry = bt.col_entry 
INNER JOIN date d 
ON bt.col_entry = d.col_entry 
GROUP BY col_entry; 

我能夠得到填充了表中的相應值視圖中的每個列,但日期和bigText列根據它們加入的原始行數重複(7次)。

(另外,作爲另一個複雜的層次......我想要讓不同的教師也能找到他們自己的專欄:Teacher_01,Teacher_02,.. Teacher_05和I'我猜這可能涉及我所得到的重大重組。)

謝謝!

... UPDATE

所以,我能夠生成查詢什麼我正在尋找其輸出的東西有點接近,但因爲有一個子查詢,我不能在視圖中使用它在FROM子句:

SELECT 
st.col_entry, 
Title, 
Course, 
Description, 
Semester, 
Location, 
Teachers 
FROM smallText st 
JOIN (SELECT smallText.col_entry, GROUP_CONCAT(if(smallText.col_inquiry_name = 'Title', smallText.col_value, NULL)) AS 'Title' 
    FROM smallText GROUP BY smallText.col_entry) a 
ON a.col_entry = st.col_entry 
JOIN (SELECT smallText.col_entry, GROUP_CONCAT(if(smallText.col_inquiry_name = 'Course', smallText.col_value, NULL)) AS 'Course' 
    FROM smallText GROUP BY smallText.col_entry) b 
ON b.col_entry = st.col_entry 
JOIN (SELECT bigText.col_entry, GROUP_CONCAT(if(bigText.col_inquiry_name = 'Description', bigText.col_value, NULL)) AS 'Description' 
    FROM bigText GROUP BY bigText.col_entry) c 
ON c.col_entry = st.col_entry 
JOIN (SELECT date.col_entry, GROUP_CONCAT(if(date.col_inquiry_name = 'Semester', date.col_value, NULL)) AS 'Semester' 
    FROM date GROUP BY date.col_entry) d 
ON d.col_entry = st.col_entry 
JOIN (SELECT smallText.col_entry, GROUP_CONCAT(if(smallText.col_inquiry_name = 'Location', smallText.col_value, NULL)) AS 'Location' 
    FROM smallText GROUP BY smallText.col_entry) e 
ON e.col_entry = st.col_entry 
JOIN (SELECT smallText.col_entry, GROUP_CONCAT(if(smallText.col_inquiry_name = 'Teachers', smallText.col_value, NULL)) AS 'Teachers' 
    FROM smallText GROUP BY smallText.col_entry) f 
ON f.col_entry = st.col_entry 
GROUP BY st.col_entry 

結果

此查詢的輸出如下所示:

Entry Title       Course  Description      Semester Location Teachers 
--------------------------------------------------------------------------------------------------------------------------------- 
1  Addition and Subtraction  Math  Lorem ipsum dolor sit amet... 1294834220 Building 7 NULL 
2  Reading Mark Twain    Literature Consectetur adipiscing elit... 1327077210 Building 4 NULL 

其中,除了空Teachers列,基本上是我在找的東西(但以某種方式生成,我可以在視圖中使用查詢)。

此外,正如我上面提到的,我希望能夠將相同的inquiry_name的多個值拉到單獨的列中。所以,最終的期望輸出將如下所示:

期望的結果

Entry Title       Course  Description      Semester Location Teachers_01 Teachers_02 Teachers_03 Teachers_04 Teachers_05 
--------------------------------------------------------------------------------------------------------------------------------- 
1  Addition and Subtraction  Math  Lorem ipsum dolor sit amet... 1294834220 Building 7 John  Jane  NULL  NULL  NULL 
2  Reading Mark Twain    Literature Consectetur adipiscing elit... 1327077210 Building 4 Billy  Bob   NULL  NULL  NULL 

謝謝!

+0

偉大的工作發佈樣本數據和表結構(以及你已經嘗試過),但你能包括一個期望的結果樣本? – Taryn

+0

更新了帖子。謝謝你的提示。 – adekom

回答

2

這是一個模擬轉PIVOT應用rownum給老師:

select s.col_entry, 
    max(case when s.col_inquiry_name = 'Title' then s.col_value end) AS 'Title', 
    max(case when s.col_inquiry_name = 'Course' then s.col_value end) AS 'Course', 
    max(case when b.col_inquiry_name = 'Description' then b.col_value end) AS 'Description', 
    max(case when d.col_inquiry_name = 'Semester' then d.col_value end) AS 'Semester', 
    max(case when s.col_inquiry_name = 'Location' then s.col_value end) AS 'Location', 
    max(case when tch.grp = 'Teachers_01' then tch.col_value end) AS 'Teachers_01', 
    max(case when tch.grp = 'Teachers_02' then tch.col_value end) AS 'Teachers_02', 
    max(case when tch.grp = 'Teachers_03' then tch.col_value end) AS 'Teachers_03', 
    max(case when tch.grp = 'Teachers_04' then tch.col_value end) AS 'Teachers_04', 
    max(case when tch.grp = 'Teachers_05' then tch.col_value end) AS 'Teachers_05' 
from smallText s 
left join bigText b 
    on s.col_entry = b.col_entry 
left join date d 
    on b.col_entry = d.col_entry 
left join 
(
    select col_entry, col_value, concat('Teachers_0', group_row_number) grp 
    from 
    (
    select col_entry, col_value, 
     @num := if(@col_entry = `col_entry`, @num + 1, 1) as group_row_number, 
     @col_entry := `col_entry` as dummy 
    from smallText , (SELECT @rn:=0) r 
    where col_inquiry_name = 'Teachers' 
     and col_value != '' 
) x 
) tch 
    on s.col_entry = tch.col_entry 
group by s.col_entry; 

看到SQL Fiddle with demo

編輯#1,根據您提供col_order附加字段,你可以用它來確定教師不使用rownum變量:

select s.col_entry, 
    max(case when s.col_inquiry_name = 'Title' then s.col_value end) AS 'Title', 
    max(case when s.col_inquiry_name = 'Course' then s.col_value end) AS 'Course', 
    max(case when b.col_inquiry_name = 'Description' then b.col_value end) AS 'Description', 
    max(case when d.col_inquiry_name = 'Semester' then d.col_value end) AS 'Semester', 
    max(case when s.col_inquiry_name = 'Location' then s.col_value end) AS 'Location', 
    max(case when s.col_inquiry_name = 'Teachers' 
     and s.col_order = 1 then s.col_value end) AS 'Teachers_01', 
    max(case when s.col_inquiry_name = 'Teachers' 
     and s.col_order = 2 then s.col_value end) AS 'Teachers_02', 
    max(case when s.col_inquiry_name = 'Teachers' 
     and s.col_order = 3 then s.col_value end) AS 'Teachers_03', 
    max(case when s.col_inquiry_name = 'Teachers' 
     and s.col_order = 4 then s.col_value end) AS 'Teachers_04', 
    max(case when s.col_inquiry_name = 'Teachers' 
     and s.col_order = 5 then s.col_value end) AS 'Teachers_05' 
from smallText s 
left join bigText b 
    on s.col_entry = b.col_entry 
left join date d 
    on b.col_entry = d.col_entry 
group by s.col_entry 

請參閱SQL Fiddle with Demo

+0

哇,這太好了。現在,是否可以在'VIEW'中做到這一點?目前在最後一個'JOIN'的'FROM'子句中有一個'SELECT',這阻止了它在視圖中可用。 – adekom

+0

@ user890857我會看看使用準備好的語句。 – Taryn

+0

那麼,我需要使用一個視圖而不是準備好的語句,因爲這是內容管理系統的一部分。我試圖將分散在多個表中的數據重新格式化爲單個視圖,以便以更基本的單行每格式格式輕鬆訪問這些數據,以便前端設計人員可以將數據從這種觀點很容易。 – adekom