MySQL大关系查询

时间:2013-10-04 13:53:31

标签: php mysql sql json

我有几张桌子:

letter_mail

index   
sent    
from    
to  
template    
public  
stamp   
stationery  
title   
content     
opened 

letter_user

index   
username    
password 

letter_mail中的所有行都是关系的,除了index,public和open之外,还有另一个表。

letter和mail中的From和To对应于letter_user的索引。我想要的是从数据库中提取所有数据,如果可能的话,最好在一个查询中。 A *在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

我需要的是,上述信息填充相关表格中的数据并进行JSON编码。看起来有点像这样:

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 
  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

查询有效,但不会返回任何行。

2 个答案:

答案 0 :(得分:2)

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

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发送任何电子邮件。

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

答案 1 :(得分:1)

简而言之,您可以使用表别名多次连接同一个表。我对其他相关的表名做了一些假设,但基本上你最终会得到一个类似这样的查询:

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_user表的多次扫描....这可能是可以避免的,但是如果此数据库具有任何真正重要的大小,则应该记住这一点。< / p>

执行这样的查询的好处,而不是整理多个数据库调用,就是让数据库完成它设计的工作,并且只对数据库进行一次调用。

当然,这个查询可以稍微重新处理以专门使用连接...但对我来说,这个表单更易于阅读和理解,假设您只需要严格关联的记录。