2012-03-12 83 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

相关问题