-1

我有几张桌子:

letter_mail

index   
sent    
from    
to  
template    
public  
stamp   
stationery  
title   
content     
opened 

信用户

index   
username    
password 

letter_mail 中的所有行都是与另一个表相关的,除了 index、public 和 opens。

letter_mail 中的 From 和 To 对应于 letter_user 的索引。我想要的是从数据库中提取所有数据,如果可能的话,最好在一个查询中。A * Select on a letter_mailrow 将产生如下结果:

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

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

4

2 回答 2

2

正如 dmcnelis 所指出的,您可以考虑使用连接(比旧的 ANSI 格式的表列表和应用 WHERE 标准更现代的语法)。这是他使用 JOIN 语法的版本。我还更改为在表上使用较短的别名引用。请注意,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 接收任何电子邮件。

如果您只想要特定的文具、邮票、标题等,请根据需要添加。

于 2013-10-04T14:46:15.227 回答
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 表进行多次扫描......这可能是可以避免的,但如果该数据库具有任何真正的显着大小,您应该记住这一点。

与整理多个数据库调用相比,像这样进行查询的好处是您让数据库完成其设计的工作,并且只对数据库进行一次调用。

当然,可以对这个查询进行一些修改以专门使用连接......但对我来说,这种形式更易于阅读和理解,假设您只需要严格相关的记录。

于 2013-10-04T14:20:36.607 回答