2012-03-12 89 views
0

我基本上這裏有完全相同的問題:MySQL視圖:連接表而不會導致數據在每一行上重複?

SQL View: Join tables without causing the data to duplicate on every row?

除非他使用SQL這個問題,而我用mysql。我想知道如果相同的查詢是可能的在MySQL中。如果是這樣,我可能會有錯誤的語法?

我試圖做類似

select a.name as account_Name, 
    p.description as property_DESCRIPTION, 
    p.address as property_ADDRESS, 
    null as vehicles_DESCRIPTION, 
    null as vehicles_MAKE, 
    null as vehicles_MODEL 
from Accounts a 
    inner join Properties p 
     on a.accountid = p.accountid 
UNION ALL 
select a.name as account_Name, 
    null as property_DESCRIPTION, 
    null as property_ADDRESS, 
    v.description as vehicles_DESCRIPTION, 
    v.make as vehicles_MAKE, 
    v.model as vehicles_MODEL 
from Accounts a 
    inner join vehicles v 
     on a.accountid = v.accountid 

這裏是我的實際代碼:

SELECT user.first_name, user.last_name, upi.image_id, NULL AS friends.friend_user_id FROM user 
INNER JOIN user_profile_images as upi ON (user.user_id = upi.user_id) 
UNION 
SELECT user.first_name, user.last_name, NULL AS upi.image_id, friends.friend_user_id FROM user 
INNER JOIN friends ON (user.user_id = friends.user_id) 
WHERE user.user_id = '$profile_id' 

在那裏我有3個表:用戶,user_profile_images,和朋友。 user_profile_images和朋友都通過user_id與用戶相關。因此,用戶可以擁有多個配置文件圖像以及多個好友條目。如果它沒有意義,我可以發佈表格圖。但是我想要的基本上是所有信息的視圖,如果它們不適用於整體視圖,則字段爲NULL。

如果我做2個表,無論是與用戶和user_profile_images,或用戶和朋友查詢時,我得到想要的結果,但加入了第三個表給我重複行。

+4

SQL是一種語言,其中MySQL是一種特殊的實現。沒有什麼是「只是SQL」。當你做'union all'時,你強制mysql返回聯合查詢中的所有行。刪除'all'關鍵字和mysql爲你刪除重複的行。 – 2012-03-12 01:51:40

+0

還閱讀左/右連接,因爲它們有時可能是更好的解決方案。 – Shomz 2012-03-12 01:56:58

+0

你的「實際代碼」可能會給出錯誤,因爲你在每個表中沒有相同的列數 - 第二個「SELECT」中有'upi.image_id',但不是第一個。 – 2012-03-12 03:46:24

回答

1

的溶液,如@MarcB所暗示的,是使用UNION而非UNION ALL

不過,我有一個問題想問你 - 爲什麼要用UNION呢?以下是等價的,不過,如果(說)賬戶1有一個屬性和一個車輛,而不是讓

account_Name property_DESCRIPTION vehicles_MAKE 
    account1   property1    NULL 
    account1   NULL    vehicle1 

你會得到

account_Name property_DESCRIPTION vehicles_MAKE 
    account1   property1   vehicle1 

查詢:

SELECT a.name as account_Name, 
    p.description as property_DESCRIPTION, 
    p.address as property_ADDRESS, 
    v.description as vehicles_DESCRIPTION, 
    v.make as vehicles_MAKE, 
    v.model as vehicles_MODEL 
FROM Accounts a 
LEFT JOIN Properties p 
     on a.accountid = p.accountid 
LEFT JOIN vehicles v 
     on a.accountid = v.accountid 
WHERE p.description IS NOT NULL AND v.make IS NOT NULL 

注 - 最後一行(IS NOT NULL的p和v)模擬INNER JOIN的「賬表」的一部分,並確保只佔機智顯示至少一個房產或車輛。替代品pv那裏id列。

+0

I' m不是很熟悉SQL,所以不知道其他的方法,只是UNION對於另一個鏈接上的問題有意義。我嘗試從UNION中刪除ALL,但是查詢仍然不起作用。左邊的加入你提到但我仍然得到重複的行,我已經更新了我的問題,以便更清楚地瞭解正在發生的事情。 – aeroshock 2012-03-12 03:19:49

+0

你的意思是「仍然沒有工作」 - 你得到重複,或者你得到一個錯誤(和什麼錯誤)?Re嘗試左連接和獲取重複行 - 你的意思是有一些行每列是相同的?他們在某些領域有所不同,您*沒有* SELECT? (我可以讓症狀消失,但可能有些不舒服的情況,所以我試圖弄清楚什麼)。你能舉一個「重複行」的例子嗎?乾杯。 – 2012-03-12 03:45:11

+0

通過不工作我的意思是我得到一個錯誤:mysqli_num_rows()期望參數1是mysqli_result,布爾給定。這讓我覺得語法錯了。對不起我在e – aeroshock 2012-03-12 04:14:30

0

如果我喜歡,其中兩個表由第三的ID相關的我會考慮使用外連接的數據後打算。在你引用的問題的評論中,外部連接被認爲是一種可能的解決方案。這個代碼看起來像這樣。

select a.name as account_Name, 
p.description as property_DESCRIPTION, 
p.address as property_ADDRESS, 
v.description as vehicles_DESCRIPTION, 
v.make as vehicles_MAKE, 
v.model as vehicles_MODEL 
from accounts a 
left outer join properties p on p.accountid = a.accountid 
left outer join vehicles v on v.accountid = a.accountid; 

以下是解決方案的測試方法。首先我創建了三張表格。

CREATE TABLE `accounts` (
`id` int(11) NOT NULL AUTO_INCREMENT, 
`name` varchar(50) COLLATE utf8_bin NOT NULL, 
PRIMARY KEY (`id`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin; 

CREATE TABLE `properties` (
`id` int(11) NOT NULL AUTO_INCREMENT, 
`accountid` int(11) NOT NULL, 
`description` varchar(255) COLLATE utf8_bin NOT NULL, 
`address` varchar(255) COLLATE utf8_bin NOT NULL, 
PRIMARY KEY (`id`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin; 

CREATE TABLE `vehicles` (
`id` int(11) NOT NULL AUTO_INCREMENT, 
`accountid` int(11) NOT NULL, 
`description` varchar(255) COLLATE utf8_bin NOT NULL, 
`make` varchar(100) COLLATE utf8_bin NOT NULL, 
`model` varchar(100) COLLATE utf8_bin NOT NULL, 
PRIMARY KEY (`id`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin; 

接下來我將數據插入到每個表中。

INSERT INTO `demo`.`accounts` (
`accountid` , 
`name` 
) 
VALUES (
NULL , 'techport80.com' 
); 

INSERT INTO `demo`.`properties` (
`id` , 
`accountid` , 
`description` , 
`address` 
) 
VALUES (
NULL , '1', 'office', '123 may street'); 

INSERT INTO `demo`.`vehicles` (
`id` , 
`accountid` , 
`description` , 
`make` , 
`model` 
) 
VALUES (
NULL , '1', 'motorcycle', 'honda', 'shadow' 
); 

此時如果我測試解決方案,我會收到一行帳戶,財產和車輛信息。

INSERT INTO `demo`.`vehicles` (
`id` , 
`accountid` , 
`description` , 
`make` , 
`model` 
) 
VALUES (
NULL , '1', 'passenger car', 'Ford', 'Mustang' 
); 

現在,如果我測試我的解決方案,我看到2行,每個車輛一個。但是這兩行並不完全重複。雖然有一些列有相同的數據。最值得注意的是,帳戶信息。

INSERT INTO `demo`.`properties` (
`id` , 
`accountid` , 
`description` , 
`address` 
) 
VALUES (
NULL , '1', 'home', '321 yam street' 
); 

接下來我添加了第二個地址。現在返回四行。每個車輛一個,每個地址一個。但是,仍然沒有任何行是重複的。

最後我加了另一輛車。這是爲了導致汽車與性能之間的不平衡。

INSERT INTO `demo`.`vehicles` (
`id` , 
`accountid` , 
`description` , 
`make` , 
`model` 
) 
VALUES (
NULL , '1', 'Van', 'Chev', 'Cargo' 
); 

現在我們有6行。每輛車和每輛車也有一個與兩個屬性相關。 (So 2 x 3)

通過這個練習,我想知道數據的分層視圖是否會成爲這個數據的更好模型。也許可以使用XML或JSON來表示數據。對於這個任務,你可以使用一個存儲函數,但我個人會首先考慮一種編程語言,比如PHP,C#,C++或其他許多函數。

HTH

+0

謝謝,我嘗試了像你說的左連接,仍然有重複的行。 – aeroshock 2012-03-12 03:26:01

相關問題