2012-03-17 4 views
0
$sth = $db->prepare("SELECT tblCompanies.*, users.Username, cargo.Name, (tblCompanies.Money + SUM(tblCTerminals.sellValue)) as assets, (COUNT(tblFinishedContracts.ID) + COUNT(tblFinishedSubContracts.ID)) as completed FROM ((((tblCompanies LEFT JOIN users ON tblCompanies.CompanyCEO = users.ID) LEFT JOIN cargo ON (tblCompanies.PreferredCargo = cargo.Cargo_ID)) LEFT JOIN tblCTerminals ON (tblCompanies.Company_ID = tblCTerminals.companyID)) LEFT JOIN tblFinishedContracts ON (tblCompanies.Company_ID = tblFinishedContracts.companyID)) LEFT JOIN tblFinishedSubContracts ON (tblCompanies.Company_ID = tblFinishedSubContracts.companyID) WHERE (users.Username LIKE :info || tblCompanies.CompanyName LIKE :info2 || CONCAT('$',FORMAT((tblCompanies.Money + SUM(tblCTerminals.sellValue)),2)) LIKE :info3 || CONCAT('$',FORMAT(tblCompanies.Money,2)) LIKE :info4 || cargo.Name LIKE :info5 || users.pLevel LIKE :info6 || CONCAT('$',FORMAT((users.Cash_In_Bank + users.Cash_In_Hand),2)) LIKE :info7)"); 

$sth->bindValue(':info', '%'.$_GET['sSearch'].'%', PDO::PARAM_STR); 
$sth->bindValue(':info2', '%'.$_GET['sSearch'].'%', PDO::PARAM_STR); 
$sth->bindValue(':info3', '%'.$_GET['sSearch'].'%', PDO::PARAM_STR); 
$sth->bindValue(':info4', '%'.$_GET['sSearch'].'%', PDO::PARAM_STR); 
$sth->bindValue(':info5', '%'.$_GET['sSearch'].'%', PDO::PARAM_STR); 
$sth->bindValue(':info6', '%'.$_GET['sSearch'].'%', PDO::PARAM_STR); 
$sth->bindValue(':info7', '%'.$_GET['sSearch'].'%', PDO::PARAM_STR); 

[OK]をので、今、この混乱のための私の推論:複数の左がの問題に参加

私はjQuery Datatablesプラグインを使用していますし、それがサーバに要求をするときにクエリを送信します。結果、検索クエリの結果の数、合計結果の数が返されます。このクエリで結果を返すことができます。

ただし、COUNT(tblFinishedContracts.ID)ではテーブルを8回取得しています。ですから、例えば代わり​​に私が行うと、それは112

の数を返す8の正確な量を返す:

SELECT COUNT(tblFinishedContracts.ID) 
FROM tblCompanies 
LEFT JOIN tblFinishedContract 
    ON (tblCompanies.Company_ID = tblFinishedContracts.ID)  
WHERE tblCompanies.Company_ID = 11 

それは動作しますが、誰かが何をやってのより良い方法を知っている場合、それは8を返します。私は達成しようとしている、またはどのように問題を解決するか教えてください、それは非常に感謝します!

おかげで、

ジェフ

EDIT:を追加するために、何の列が重複した名前を持っていないすべてが異なっています。

答えて

1

この問題のための単一の弾丸はありません。親テーブルに関する情報を取得する一方、一対多の関係を持つ複数の子テーブルから情報を取得することは、常に難しいです。しかし、助けることができるいくつかのテクニックがあります。

まず、実際にはtblFinishedContractsで何もしないでください。ただし、そこからレコードの数を得ることはできません。したがって、COUNT(tblFinishedContracts.ID)を記述し、結合を使用する代わりに、サブクエリ:write (SELECT COUNT(1) FROM tblFinishedContracts WHERE Company_ID = tblCompanies.Company_ID)を使用することができます。同じことがtblFinishedSubContractsに適用されるため、その結合も排除できます。 (実際に返されている会社に属する契約に関する情報を取得するだけで済むため、これらの結合を削除するとパフォーマンスが大幅に向上するはずです)。

これは、のうち、最も多くのを処理します。問題。最高経営責任者(CEO)と優先貨物を得るためにuserscargoへの参加は、問題を引き起こしてはいけません。

SUM(tblCTerminals.sellValue)フィールドがフィールドリストとWHERE節の両方に存在するので、残りの難易度はtblCTerminalsです。それを処理するための魅力的な方法はありません。 1つのオプションは、サブクエリの2つのコピーを使用して、前述のサブクエリ手法を使用することです。もう1つは、FROM tblCompaniesFROM (SELECT tblCompanies.*, COALESCE(SUM(tblCTerminals.sellValue), 0) AS totalCTerminalSellValue FROM tblCompanies LEFT JOIN tblCTerminals ON tblCTerminals.Company_ID = tblCompanies.Company_ID GROUP BY tblCompanies.Company_ID) AS tblCompaniesに置き換えることです。tblCompaniesの一時コピーが作成され、totalCTerminalSellValueという新しいフィールドが追加されています。したがって、クエリの別の場所では、SUM(tblCTerminals.sellValue)tblCompanies.totalCTerminalSellValueに置き換えることができます。

+0

これは私が今使っているものですが、正しい構文が正しいかどうかを確認するエラーが表示されます。「SELECT 1 FROM tblFinishedSubContracts WHERE companyID = tblCompanies.Company_ID」 ':' SELECT COUNT(SELECT 1 FROM tblFinishedSubContracts WHERE (tblCompanies.PreferredCargo = cargo.Cargo_ID)LEFT JOIN tblCTerminals ON(tblCompanies.Company_ID = tblCTerminals.companyID))LEFT JOINユーザをtblCompanies.CompanyCEO = users.IDにLEFT JOINします。 )WHERE tblCompanies.Company_ID = 7'何が間違っているのか分かりません。 – jefffan24

+0

@ jefffan24:私のせいで、括弧をはずしました。 'COUNT(SELECT ...)'は 'COUNT((SELECT ...))) '(一方の組は' COUNT'に属し、引数を区切ります;他方はサブクエリに属します)。私は私の答えを訂正しました。 – ruakh

+0

新しい問題:サブクエリは1行以上を返します...そのタイプのサブクエリを処理できますか? – jefffan24