Sql从多个表中选择,其中不起作用

时间:2016-08-16 19:01:08

标签: php mysql sql

我正在创建一个网页,其中有多个页面,每个页面在数据库中都有一个表格,当您按照自己喜欢的页面时。我希望您关注的网页中的帖子显示在您的新闻源中。这将需要从多个表中进行选择。这是我到目前为止所尝试的:

Select page-id, id, content
from page1, page2, page3, page4
where page-id in(select p_id from follows where p_username = '$me')

但是我收到了这个错误:

Column 'page-id' in field list is ambiguous

帮助?

4 个答案:

答案 0 :(得分:3)

Yuo必须将表名分配给列,因为有更多表具有相同的列名,例如:

  "Select page1.page-id, page2.page-id, id,content 
  from  page1,page2,page3,page4 
  where page1.page-id in(select p_id from follows where p_username='$me')"

或者如果您需要为所有表选择相同的列,您可以使用union

  "Select page-id,  id, content 
  from  page1
  where page-id in(select p_id from follows where p_username='$me')
  union 
  Select page-id,  id, content 
  from  page2
  where page-id in(select p_id from follows where p_username='$me')
  union 
  Select page-id,  id, content 
  from  page3
  where page-id in(select p_id from follows where p_username='$me')
  union
  Select page-id,  id, content 
  from  page4
  where page-id in(select p_id from follows where p_username='$me')

答案 1 :(得分:1)

Column 'page-id' in field list is ambiguous

这意味着" page-id"在多个表中找到它,您必须使用表名来标识或别名

Select a.page-id, id, content
from page1 a, page2 b, page3 c, page4 d
where a.page-id in(select p_id from follows where p_username = '$me')

但我不认为你想要查询的是什么,你必须解释更多。

编辑,阅读scaisEdge的回答

如果要将所有表都作为一个表,则需要UNION

 (SELECT page-id, id, content
  FROM page1
  WHERE page-id in(SELECT p_id FROM follows WHERE p_username = '$me'))
UNION
 (SELECT page-id, id, content
  FROM page2
  WHERE page-id in(SELECT p_id FROM follows WHERE p_username = '$me'))
UNION
 (SELECT ...) ...

但是,你知道页数吗?你可以使用php进行查询 动态。

答案 2 :(得分:1)

为什么您的查询无法执行您想要的操作

JOIN生成四列page-id列,四列id列,四列content列。 SELECT无法自动确定您想要的哪一个。将LEFT JOINCOALESCE(解决方案1)一起使用,或将四个不同的查询与UNION一起使用(解决方案2)。考虑修改表格架构(建议)。

解决方案1 ​​

此解决方案在联接的左侧使用LEFT JOINfollows。这意味着结果集中的每一行都将基于follows中的一行。其他表中的列也将被选中,但如果没有匹配则它们将为null。 COALESCE函数选择第一个非空值。此解决方案假设page-id在表中是唯一的,idcontentpage-id不为空时为非空。

SELECT COALESCE(p1.`page-id`, p2.`page-id`, p3.`page-id`, p4.`page-id`) `page-id`
     , COALESCE(p1.id, p2.id, p3.id, p4.id) id
     , COALESCE(p1.content, p2.content, p3.content, p4.content) content
  FROM (((  follows f LEFT JOIN page1 p1 ON f.p_id = p1.`page-id`
         ) LEFT JOIN page2 p2 ON f.p_id = p2.`page-id`
        ) LEFT JOIN page3 p3 ON f.p_id = p3.`page-id`
       ) LEFT JOIN page4 p4 ON f.p_id = p4.`page-id`
 WHERE f.p_username = '$me'
;

解决方案2

SELECT使用单独的UNION语句。请参阅scaisEDGE的解决方案(上图)。我使用JOIN代替IN子查询。根据我的经验,IN - with-subquery的可伸缩性较低,并且根据数据库服务器和资源的不同,可能会产生性能问题。

SELECT `page-id`, id, content
  FROM page1 INNER JOIN follows ON `page-id` = p_id
 WHERE p_username = '$me'
UNION
SELECT `page-id`, id, content
  FROM page2 INNER JOIN follows ON `page-id` = p_id
 WHERE p_username = '$me'
UNION
SELECT `page-id`, id, content 
  FROM page3 INNER JOIN follows ON `page-id` = p_id
 WHERE p_username = '$me'
UNION
SELECT `page-id`, id, content
  FROM page4 INNER JOIN follows ON `page-id` = p_id
 WHERE p_username = '$me'
;

建议

表架构似乎有问题。

  • 您如何保证page-id是唯一的?
  • 为什么每个页面都有一个单独的表格?拥有一个pages表似乎更有意义。每行应标识页面。如果您需要单独的物理文件(例如,用于分片),请考虑进行分区。
  • 在名称page-id中使用连字符可能很难使某些验证器和IDE解释为不同的列名。作为最佳实践,请考虑在列名中仅使用字母,数字和下划线。在我的例子中,我用反引号将它包围起来告诉MySQL和IDE它是一个对象名。我建议page_id作为更好的选择。

答案 3 :(得分:0)

在查询大型数据集时,使用EXISTS代替IN可获得更好的性能,对于数百行INEXISTS的较小数据集,不会产生太大影响差异

Select page1.page-id, page2.page-id,content 
  from  page1,page2,page3,page4 
  where exists (select p_id from follows where page1.page-id=follows.p_id and p_username='$me')