-1

私はいくつかのテーブルを持っています:

letter_mail

index   
sent    
from    
to  
template    
public  
stamp   
stationery  
title   
content     
opened 

letter_user

index   
username    
password 

index、public、opened を除いて、letter_mail のすべての行は、別のテーブルと関係があります。

letter_mail の From と To は、letter_user のインデックスに対応します。私が望むのは、データベースからすべてのデータを、可能であれば 1 つのクエリで取得することです。行を* 選択すると、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

これは完全にクレイジーですか?クエリをいくつかのビットに分割するか、すべてを 1 つのテーブルにまとめて照合する必要がありますか?

さらに情報が必要な場合はお知らせください:)

解決策はこれです:

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 が指摘したように、結合を使用することを検討できます (テーブルを一覧表示して WHERE 条件を適用する古い ANSI 形式よりも新しい構文)。JOIN 構文を使用した彼のバージョンは次のとおりです。また、テーブルで短いエイリアス名参照を使用するように変更しました。JOIN/ON は、WHERE 句に埋め込まれているのではなく、tableX が tableY にどのように関連しているかを正確に示していることに注意してください。OOps が 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 との間で任意の電子メールを取得します。

特定のステーショナリー、スタンプ、タイトルなどのみが必要な場合は、必要に応じて追加してください。

于 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 テーブルの複数のスキャンが発生することです....これは回避できるかもしれませんが、このデータベースに実際に大きなサイズがある場合は、覚えておく必要があります。

複数の db 呼び出しを照合するのではなく、このようなクエリを実行する利点は、db に設計された作業を実行させ、データベースへの呼び出しを 1 回だけ行うことです。

もちろん、このクエリは結合を具体的に使用するために少し作り直すことができます...しかし、私にとっては、厳密に相関したレコードのみが必要であると仮定すると、このフォームの方が読みやすく理解しやすいです。

于 2013-10-04T14:20:36.607 に答える