Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/262.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php MySQL大型关系查询_Php_Mysql_Sql_Json - Fatal编程技术网

Php MySQL大型关系查询

Php MySQL大型关系查询,php,mysql,sql,json,Php,Mysql,Sql,Json,我有几张桌子: 信件(邮件) index sent from to template public stamp stationery title content opened index username password 字母用户 index sent from to template public stamp stationery title conte

我有几张桌子:

信件(邮件)

index   
sent    
from    
to  
template    
public  
stamp   
stationery  
title   
content     
opened 
index   
username    
password 
字母用户

index   
sent    
from    
to  
template    
public  
stamp   
stationery  
title   
content     
opened 
index   
username    
password 
除了索引、public和opened之外,letter_mail中的所有行都与另一个表相关

信函中的“发件人”和“收件人”对应于信函用户的索引。我想要的是从数据库中提取所有数据,如果可能,最好是在一个查询中。在
信件
行中选择*将产生如下结果:

index:1     
sent: 2013-10-03    
from:1  
to:2    
template:1  
public:1    
stamp:1     
stationery:1    
title: 1    
content: 1  
opened : 0
index:1     
sent: 2013-10-03    
from: {1, John}     
to: {2, Jane}   
template: {index: 1, template: "standard template", url: "template_name"}   
public: 0       
stamp: {index: 1, stamp: "standard stamp", url: "some/url"}     
stationery: {index: 1, stamp: "standard stationery", url: "some/url"}       
title: {index: 1, title: "some title"}      
content: {index: 1, content: "some text content"}       
opened : 0
select 
    sent, from.username, to.username, template_table.name, template_table.url, public, 
    stamp_table.stamp, stamp_table.url, stationary_table.stamp, stationary_table.url, title_table.title, 
    content_table.content, opened
from 
    letter_mail l, 
    letter_user from, 
    letter_user to, 
    template template_table, 
    stamp stamp_table, 
    stationairy stationary_table, 
    title title_table, 
    content content_table
where 
    l.from = from.idex
    and l.to = to.index
    and template = template_table.index
    and stamp = stamp_table.index
    and stationairy = stationary_table.index
    and title = title_table.index
    and content = content_table.index
    where l.index = X
我需要的是用相关表格中的数据填充上述信息,并对其进行
JSON
编码。看起来有点像这样:

index:1     
sent: 2013-10-03    
from:1  
to:2    
template:1  
public:1    
stamp:1     
stationery:1    
title: 1    
content: 1  
opened : 0
index:1     
sent: 2013-10-03    
from: {1, John}     
to: {2, Jane}   
template: {index: 1, template: "standard template", url: "template_name"}   
public: 0       
stamp: {index: 1, stamp: "standard stamp", url: "some/url"}     
stationery: {index: 1, stamp: "standard stationery", url: "some/url"}       
title: {index: 1, title: "some title"}      
content: {index: 1, content: "some text content"}       
opened : 0
select 
    sent, from.username, to.username, template_table.name, template_table.url, public, 
    stamp_table.stamp, stamp_table.url, stationary_table.stamp, stationary_table.url, title_table.title, 
    content_table.content, opened
from 
    letter_mail l, 
    letter_user from, 
    letter_user to, 
    template template_table, 
    stamp stamp_table, 
    stationairy stationary_table, 
    title title_table, 
    content content_table
where 
    l.from = from.idex
    and l.to = to.index
    and template = template_table.index
    and stamp = stamp_table.index
    and stationairy = stationary_table.index
    and title = title_table.index
    and content = content_table.index
    where l.index = X
这完全疯了吗?我应该把查询分成几个部分,还是把所有内容都整理成一个表

如果您需要更多信息,请告知:)

解决方案如下所示:

select 
  mail.index,
  mail.sent,
  mail.opened,
  mail.public, 
  FromU.username as FromUser, 
  ToU.username as ToUser, 
  T.template as TemplateName, 
  T.url as TemplateURL, 
  S.stamp, 
  S.url as StampURL, 
  S.stamp Stamp, 
  STA.url StationaryURL, 
  Ttl.title, 
  C.content
from 
  letter_mail mail
     JOIN letter_user FromU
        on mail.from = FromU.index 
     JOIN letter_user ToU
        on mail.to = ToU.index 
     JOIN letter_templates T
        on mail.template = T.index
     JOIN letter_stamps S
        on mail.stamp = S.index
     JOIN letter_stationery STA
        on mail.stationery = STA.index 
     JOIN letter_title Ttl
        on mail.title = Ttl.index 
     JOIN letter_content C
        on mail.content = C.index

查询可以工作,但不返回任何行。

简而言之,您可以使用表别名多次联接同一个表。我对其他相关的表名做了一些假设,但基本上最终得到的查询如下所示:

index:1     
sent: 2013-10-03    
from:1  
to:2    
template:1  
public:1    
stamp:1     
stationery:1    
title: 1    
content: 1  
opened : 0
index:1     
sent: 2013-10-03    
from: {1, John}     
to: {2, Jane}   
template: {index: 1, template: "standard template", url: "template_name"}   
public: 0       
stamp: {index: 1, stamp: "standard stamp", url: "some/url"}     
stationery: {index: 1, stamp: "standard stationery", url: "some/url"}       
title: {index: 1, title: "some title"}      
content: {index: 1, content: "some text content"}       
opened : 0
select 
    sent, from.username, to.username, template_table.name, template_table.url, public, 
    stamp_table.stamp, stamp_table.url, stationary_table.stamp, stationary_table.url, title_table.title, 
    content_table.content, opened
from 
    letter_mail l, 
    letter_user from, 
    letter_user to, 
    template template_table, 
    stamp stamp_table, 
    stationairy stationary_table, 
    title title_table, 
    content content_table
where 
    l.from = from.idex
    and l.to = to.index
    and template = template_table.index
    and stamp = stamp_table.index
    and stationairy = stationary_table.index
    and title = title_table.index
    and content = content_table.index
    where l.index = X
您将遇到的主要问题是,这将导致多次扫描letter_用户表。。。。这可能是可以避免的,但如果这个数据库有任何实际的重要大小,您应该记住这一点

这样做的好处是,与整理多个db调用不同,您可以让db完成其设计的工作,并且只对数据库进行一次调用


当然,这个查询可以重新处理一点,专门使用连接。。。但对我来说,这种形式更容易阅读和理解,假设你只想要严格相关的记录。

如DMCNELIS所指出的,你可以考虑使用连接(更大的语法,而不是更大的ANSI格式的列表和应用标准)。这是他使用连接语法的版本。。我还改为在表上使用更短的别名引用。请注意,JOIN/ON准确地显示了tableX与tableY的关系,而不是隐藏在WHERE子句中。如果OOps忘记where子句,这有时会导致问题和笛卡尔结果。通过加入,您将立即看到您的关系标准

select 
      L.sent, 
      FromU.username as FromUser, 
      ToU.username as ToUser, 
      T.name as TemplateName, 
      T.url as TemplateURL, 
      L.public, 
      S.stamp, 
      S.url as StampURL, 
      STA.stamp StationaryStamp, 
      STA.url StationaryURL, 
      title.title, 
      C.content, 
      L.opened
   from 
      letter_mail L
         JOIN letter_user FromU
            on L.from = FromU.index 
         JOIN letter_user ToU
            on L.to = ToU.index 
         JOIN template T
            on L.Template = T.index
         JOIN stamp S
            on L.Stamp = S.index
         JOIN stationary STA
            on L.Stationary = STA.index 
         JOIN title
            on L.title = title.index 
         JOIN content C
            on L.Content = C.index
既然所有的表都是相关的,那么运行查询,它就会得到所需的一切。但是,如果您要查找某一组标准的内容,只需添加WHERE子句。。。比如

WHERE
      L.From = 27
   OR L.To = 27
获取任何发送至或来自用户27的电子邮件


如果您只需要特定的文具、图章、标题等,只需根据需要添加即可。

这并不疯狂-尽管您最终会得到大量重复数据,在一个查询中一次获取所有数据。这是否是一个好主意取决于数据的数量以及从Web服务器到数据库的接近程度/连接。我只是想避免9个select查询,但如果这是需要的话……是的。我可以将查询中的所有数据存储在主表中,但这也会在查询一件事情时增加开销。还有,如果人们投了票,请告诉我为什么:不是我——有些人只是把他们认为基本的问题记下来。不要将所有数据放在一个表中,除非它应该放在一个表中,否则应避免数据重复,并且数据重复是关系数据库的主要点。您应该只需要两个查询,尽管每个表一个查询。链接可以在PHP中完成。这有意义吗?或者我应该重组DB吗?我看你是怎么把事情搞糟的没有什么错。。。在数据库中有许多查找表是很常见的。想想看,如果你有100000条记录,并且不得不重复固定类型“标准固定”与内部ID 8。那你拼写错了?在查找表中进行修复,您就完成了。你的上下文看起来不错,很有效!非常感谢。我已经用你的答案更新了这个问题,并用投票数奖励任何获得这个答案的人。@Eirinn,更大的元素。。。您现在看到了连接与来自/来自组合的相关性了吗,如dmcnelis所示,两者都是有效的,但是连接在实际查询中更为活跃。嗯,这是为了防止多次扫描表?