2012-03-26 15 views
0

高度な(私のために)クエリを作成する際に問題があります。MySQLサンプルの従業員データベースを使用したSQLクエリ

私はマネージャの名字、姓、役職名、姓名を取得しようとしています。私は何らかの理由であなたが知る必要があった場合、PHPでこのSQLを使用しています。データベースが膨大であるため、私は10に制限されています。従業員の最新データを入力する必要があります。彼らは仕事の促進などのために複数のエントリーを持っています。

私はあなたが私の問題を理解する必要があると思うすべてを含んでいました。助けていただければありがとうございます。

mysql> 
SELECT DISTINCT employees.first_name, employees.last_name, 
titles.title, departments.dept_name, z.first, z.last 
FROM employees, dept_emp, departments, titles, 
(
    SELECT employees.first_name AS first, employees.last_name AS last 
    FROM employees, dept_emp, dept_manager 
    WHERE 
     employees.emp_no = dept_emp.emp_no 
     AND dept_manager.emp_no = dept_emp.emp_no 
) AS z 
WHERE 
    employees.emp_no = dept_emp.emp_no 
    AND dept_emp.dept_no = departments.dept_no 
    AND titles.emp_no = employees.emp_no 
LIMIT 10; 

+------------+-----------+-----------------+-------------+-----------+--------------+ 
| first_name | last_name | title   | dept_name | first  | last   | 
+------------+-----------+-----------------+-------------+-----------+--------------+ 
| Georgi  | Facello | Senior Engineer | Development | Margareta | Markovitch | 
| Georgi  | Facello | Senior Engineer | Development | Vishwani | Minakawa  | 
| Georgi  | Facello | Senior Engineer | Development | Ebru  | Alpin  | 
| Georgi  | Facello | Senior Engineer | Development | Isamu  | Legleitner | 
| Georgi  | Facello | Senior Engineer | Development | Shirish | Ossenbruggen | 
| Georgi  | Facello | Senior Engineer | Development | Karsten | Sigstam  | 
| Georgi  | Facello | Senior Engineer | Development | Krassimir | Wegerle  | 
| Georgi  | Facello | Senior Engineer | Development | Rosine | Cools  | 
| Georgi  | Facello | Senior Engineer | Development | Shem  | Kieras  | 
| Georgi  | Facello | Senior Engineer | Development | Oscar  | Ghazalie  | 
+------------+-----------+-----------------+-------------+-----------+--------------+ 
10 rows in set (0.00 sec) 

データベースはmysql.comから、従業員のデータベースです: http://dev.mysql.com/doc/index-other.html

mysql> desc departments; 
+-----------+-------------+------+-----+---------+-------+ 
| Field  | Type  | Null | Key | Default | Extra | 
+-----------+-------------+------+-----+---------+-------+ 
| dept_no | char(4)  | NO | PRI | NULL |  | 
| dept_name | varchar(40) | NO | UNI | NULL |  | 
+-----------+-------------+------+-----+---------+-------+ 
2 rows in set (0.22 sec) 

mysql> desc dept_emp; 
+-----------+---------+------+-----+---------+-------+ 
| Field  | Type | Null | Key | Default | Extra | 
+-----------+---------+------+-----+---------+-------+ 
| emp_no | int(11) | NO | PRI | NULL |  | 
| dept_no | char(4) | NO | PRI | NULL |  | 
| from_date | date | NO |  | NULL |  | 
| to_date | date | NO |  | NULL |  | 
+-----------+---------+------+-----+---------+-------+ 
4 rows in set (0.20 sec) 

mysql> desc dept_manager; 
+-----------+---------+------+-----+---------+-------+ 
| Field  | Type | Null | Key | Default | Extra | 
+-----------+---------+------+-----+---------+-------+ 
| dept_no | char(4) | NO | PRI | NULL |  | 
| emp_no | int(11) | NO | PRI | NULL |  | 
| from_date | date | NO |  | NULL |  | 
| to_date | date | NO |  | NULL |  | 
+-----------+---------+------+-----+---------+-------+ 
4 rows in set (0.21 sec) 

mysql> desc employees; 
+------------+---------------+------+-----+---------+-------+ 
| Field  | Type   | Null | Key | Default | Extra | 
+------------+---------------+------+-----+---------+-------+ 
| emp_no  | int(11)  | NO | PRI | NULL |  | 
| birth_date | date   | NO |  | NULL |  | 
| first_name | varchar(14) | NO |  | NULL |  | 
| last_name | varchar(16) | NO |  | NULL |  | 
| gender  | enum('M','F') | NO |  | NULL |  | 
| hire_date | date   | NO |  | NULL |  | 
+------------+---------------+------+-----+---------+-------+ 
6 rows in set (0.32 sec) 

mysql> desc salaries; 
+-----------+---------+------+-----+---------+-------+ 
| Field  | Type | Null | Key | Default | Extra | 
+-----------+---------+------+-----+---------+-------+ 
| emp_no | int(11) | NO | PRI | NULL |  | 
| salary | int(11) | NO |  | NULL |  | 
| from_date | date | NO | PRI | NULL |  | 
| to_date | date | NO |  | NULL |  | 
+-----------+---------+------+-----+---------+-------+ 
4 rows in set (0.34 sec) 

mysql> desc titles; 
+-----------+-------------+------+-----+---------+-------+ 
| Field  | Type  | Null | Key | Default | Extra | 
+-----------+-------------+------+-----+---------+-------+ 
| emp_no | int(11)  | NO | PRI | NULL |  | 
| title  | varchar(50) | NO | PRI | NULL |  | 
| from_date | date  | NO | PRI | NULL |  | 
| to_date | date  | YES |  | NULL |  | 
+-----------+-------------+------+-----+---------+-------+ 
4 rows in set (0.60 sec) 
+1

をので、問題は何ですか?エラーメッセージが表示されますか?あなたが期待している結果と異なる結果が出ますか? –

+0

また、markdownの概要については、http://stackoverflow.com/editing-helpを参照してください。ポストを編集しているときにツールバーに表示されます。また、アイコンの上にマウスを置くと、自分が何をしているかがわかります。 "コードブロック"(これは4つのスペースをインデントすることによって行われます)に変わるテキストのブロックを選択する場所があります。中括弧 '{}'のように見えます。 –

+0

あなたの記事を読みやすくするために編集しました。それを受け入れてください。そして、ベンリーが言ったように、あなたの問題は何ですか – grifos

答えて

1

私は姓、名、役職、部署名、および最初と最後を取得しようとしていますマネージャーの名前

理論を使用します(ただし、テーブルが大きい場合は最適化されていない可能性があります)。日付が含まれている$date PHP変数(date('Y-m-d 00:00:00')の結果のようなもの)があると仮定するか、またはMySQLの日付を使用することができます。

1 /従業員のアイデンティティを取得:

SELECT 
    e.first_name, 
    e.last_name 
FROM 
    employees AS e 
WHERE 
    1 

2 /彼/彼女の現在のタイトルを追加

SELECT 
    e.first_name, 
    e.last_name, 
    t.title 
FROM 
    employees AS e, 
    titles AS t 
WHERE 
    e.emp_no=t.emp_no AND t.from_date<='$date' AND t.to_date>='$date' 

3 /(dept_empから)彼/彼女の現在の部署を取得し、部門の名前を取得します

SELECT 
    e.first_name, 
    e.last_name, t.title, 
    d.dept_name 
FROM 
    employees AS e, 
    titles AS t, 
    dept_emp AS de, 
    departments as d 
WHERE 
    e.emp_no=t.emp_no AND t.from_date<='$date' AND t.to_date>='$date' 
AND 
    e.emp_no=de.emp_no AND de.from_date<='$date' AND de.to_date>='$date' 
AND 
    d.dept_no=de.dept_no 

4 /(dept_managerから)部門のマネージャを取得して再あなたはLIMIT(およびORDER BYおそらく、あなたが制限の場合に取得されますどの結果がわからない)、および/またはアドインを追加することができます(employeesから)彼/彼女の名前

あり
SELECT 
    e.first_name AS empFN, 
    e.last_name AS empLN, 
    t.title AS empT, 
    d.dept_name AS dept, 
    em.first_name AS manFN, 
    em.last_name AS manLN 
FROM 
    employees AS e, 
    titles AS t, 
    dept_emp AS de, 
    departments as d, 
    dept_manager AS dm, 
    employees AS em 
WHERE 
    e.emp_no=t.emp_no AND t.from_date<='$date' AND t.to_date>='$date' 
AND 
    e.emp_no=de.emp_no AND de.from_date<='$date' AND de.to_date>='$date' 
AND 
    d.dept_no=de.dept_no 
AND 
    em.emp_no=dm.emp_no AND dm.from_date<='$date' AND dm.to_date>='$date' 
AND 
    de.dept_no=dm.dept_no 

をtrieve情報が必要な従業員のWHEREemp_noを入力します。テストされていませんが、主にリクエストの作成方法を理解できるようにしています。

これは理論であり、この要求はおそらくあなたが書いたものと同じくらい重いものです。 PHPでSQLを使用しているので、興味のある主キーのみを取得し、必要な情報を取得するために短いリクエストを送信するほうがよい場合があります。私は(偽の機能を使用してが、精神はここにある)を意味するそのような何か:

$dateString="from_date<='$date' AND to_date>='$date'"; 
$qe=query("SELECT emp_no, first_name, last_name, dept_no FROM employees, dept_emp WHERE dept_emp.emp_no=employees.emp_no LIMIT 10 ORDER BY emp_no DESC"); 
while($r=fetch($qe)) { 
    $qt=fetch(query("SELECT title FROM titles WHERE emp_no=".$qe['emp_no']." AND ".$dateString)); 
    $qd=fetch(query("SELECT dept_name FROM departments WHERE dept_no=".$qe['dept_no']." AND ".$dateString)); 
    $qm=fetch(query("SELECT first_name, last_name FROM employees AS e, dept_manager AS dm WHERE dept_no=".$qe['dept_no']." AND e.emp_no=dm.emp_no AND ".$dateString)); 
    //echo/process here 
} 

・ホープ、このことができます:)

+0

それは役に立ちます。実際にはちょっと。 LIMITとORDER BYを実行したいのですが、例えばList All - ページング制限値50などを使用し、1つ以上の部門別にソートするだけです... ORDERに追加するとempFN LIMIT 10かそれに類するものによって、MySQLが停止します。ところで、私はPHPサイトではなくMySQLでこれを試してみました。 – leeman24

+0

それはどういうことですか? MySQLがクラッシュしますか?ログの中の何か(特に、[低速クエリ](http://dev.mysql.com/doc/refman/5.1/en/slow-query-log.html)メカニズム:ログと設定)の周り?とにかく、あなたの目標が部署別にソートすることであるなら(あなたの "1つ以上の"部分で何を理解するか分からない)、 'dept_no'で' ORDER BY'を使用してください:いずれの場合でも ' ORDER BY'(そして 'employees.first_name'はおそらく索引付けされていません)、特にそれが適用される要求が巨大な結果を返すときには、"もっと遅くなります "(私は非常に遅いという意味です)。 –

+0

とにかくあなたが処理できるリクエストが非常に多いので、[ビュー](http://dev.mysql.com/doc/refman/5.0/ja/create-view.html)または[一時テーブル](http://dev.mysql.com/doc/refman/5.1/en/create-table.html)を使用して、ページがリロードされるたびにこの大きな不良リクエストを送信しないようにします。このようにして、PHPページからのリクエストは非常に高速になります(基本的に 'SELECT * FROM your_view WHERE 1 ORDER BY some_field LIMIT $ offset、10'のようなものです)。ビューのプロ:サーバー上で一度だけ作成されます。短所:インデックスなし。 TempTableプロ:インデックスを定義できます。短所:接続中にのみ作成されます。 –

関連する問題