2011-04-27 5 views
2

をクリーンアップする必要がヤオールねえ、私は、クエリの恐ろしい混乱を持って、誰もがそれを見て、私はそれをクリーンアップする方法の任意の提案をお知らせできればと思いまして。それは動作しますが、あまりにも多くのレコードがそこにあるとゆっくり実行されます。これは2つのテーブルのみを含みますが、問合せは基本的にproblem_nodes表の行から値を取り出し、最終結果の列に変換します。ひどくフォーマットされたSQLクエリは、

SELECT * 
FROM (SELECT urgency, 
       name, 
       phone, 
       location, 
       department, 
       cc, 
       status, 
       case_manager, 
       ip, 
       case_manager_ei d, 
       id_problem, 
       id_problem_type, 
       eid_author, 
       title, 
       body, 
       date_created, 
       date_modified 
     FROM problems AS main 
       INNER JOIN (SELECT id_problem as t_urgency_id_problem, 
            node_value AS urgency 
          FROM problem_nodes 
          WHERE node_name = "urgency")t_urgency 
       ON t_urgency.t_urgency_id_problem = main.id_problem 
       INNER JOIN (SELECT id_problem as t_name_id_problem, 
            node_value AS name 
          FROM problem_nodes 
          WHERE node_name = "name")t_name 
       ON t_name.t_name_id_problem = main.id_problem 
       INNER JOIN (SELECT id_problem as t_phone_id_problem, 
            node_value AS phone 
          FROM problem_nodes 
          WHERE node_name = "phone")t_phone 
       ON t_phone.t_phone_id_problem = main.id_problem 
       INNER JOIN (SELECT id_problem as t_location_id_problem, 
            node_value AS location 
          FROM problem_nodes 
          WHERE node_name = "location")t_location 
       ON t_location.t_location_id_problem = main.id_problem 
       INNER JOIN (SELECT id_problem as t_department_id_problem, 
            node_value AS department 
          FROM problem_nodes 
          WHERE node_name = "department")t_department 
       ON t_department.t_department_id_problem = main.id_problem 
       INNER JOIN (SELECT id_problem as t_cc_id_problem, 
            node_value AS cc 
          FROM problem_nodes 
          WHERE node_name = "cc")t_cc 
       ON t_cc.t_cc_id_problem = main.id_problem 
       INNER JOIN (SELECT id_problem as t_status_id_problem, 
            node_value AS status 
          FROM problem_nodes 
          WHERE node_name = "status")t_status 
       ON t_status.t_status_id_problem = main.id_problem 
       INNER JOIN (SELECT id_problem as t_case_manager_id_problem, 
            node_value AS case_manager 
          FROM problem_nodes 
          WHERE node_name = "case_manager")t_case_manager 
       ON t_case_manager.t_case_manager_id_problem = main.id_problem 
       INNER JOIN (SELECT id_problem as t_ip_id_problem, 
            node_value AS ip 
          FROM problem_nodes 
          WHERE node_name = "ip")t_ip 
       ON t_ip.t_ip_id_problem = main.id_problem 
       INNER JOIN (SELECT id_problem as t_case_manager_eid_id_problem, 
            node_value AS case_manager_eid 
          FROM problem_nodes 
          WHERE node_name = "case_manager_eid") 
          t_case_manager_eid 
       ON t_case_manager_eid.t_case_manager_eid_id_problem = 
     main.id_problem)t 

データを取得する。このパターンは、私には少し外国人なので、任意の助けいただければ幸いです。

+1

私は(それがどのように見えるか)あなたの問題は、フォーマットではないと思うが、それは_does_と_how_何でそれはそれをしません。 – Oded

+0

実装ピボットの奇妙な方法.... –

+0

そしてまた、それは一つの問題のために、それはすべての問題のノードを持つことを前提とし、私はいつもケースのthatsを不思議に思う....しかし、インナーがクエリに参加することは同じことを示唆して....そして、 al –

答えて

4

あなたは代わりにこのPIVOT手法を試みることができます。私は最初の2件を行った。残りの部分をどのように拡張するのかを見てください。

SELECT main.*, 
      MAX(CASE WHEN node_name = 'urgency' THEN node_value END) AS urgency, 
      MAX(CASE WHEN node_name = 'name' THEN node_value END) AS name 
    FROM problems AS main INNER JOIN 
     problem_nodes pn ON pn.id_problem = main.id_problem 
    WHERE node_name IN ('urgency','name') 
    GROUP BY main.id_problem 
+0

素晴らしい、ありがとう!私はこれが最も簡潔な実装だと思っています。クエリは今より速く実行されています。あなたが気にしないならもう1つの質問。私は今、緊急度フィールドで結果をフィルタリングしようとしています: どこのノード名( '緊急'、 '名前'、 '電話'、 '場所'、 '部署'、 'C​​C'、 'ステータス'、 'case_manager' しかし、緊急性が明らかに未知のコラムで「いつでも」「IP」、「case_manager_eid」) 性と緊急性=。これを解決するにはどうすればいいですか? – jwBurnside

+0

'GROUP BY main.id_problem HAVING urgency = whatever'を使用します。MySQLでは、列の別名を参照できます。 –

+0

クール、大きな助けになりました、もう一度ありがとう! – jwBurnside

1

これは基本的にEAV

副問い合わせが不要なある - それは、このフォームでクリーンアップすることができます。

SELECT t_urgency.node_value AS urgency, 
     main.id_problem, 
FROM problems AS main 
INNER JOIN problem_nodes AS t_urgency 
    ON t_urgency.id_problem = main.id_problem 
    AND t_urgency.node_name = "urgency" 

私はINNERの排他的使用は、潜在的な問題をされるJOINのことに注意しますなぜなら、結果セットがその行を含むためには、problem_nodesテーブルに属性が存在しなければならないからです。

0

元のクエリは、基本的にEAV modelを照会するための非常に扱いにくい方法です。あなたはそれらのすべてのジョインを必要としません。必要なのは、一連の相関サブクエリだけです。これを試してみてください:

SELECT 
    (SELECT node_value FROM problem_nodes WHERE node_name = "urgency" AND id_problem = p.id_problem) AS t_urgency,        
    (SELECT node_value FROM problem_nodes WHERE node_name = "name" AND id_problem = p.id_problem) AS t_name, 
    (SELECT node_value FROM problem_nodes WHERE node_name = "phone" AND id_problem = p.id_problem) AS t_phone, 
    (SELECT node_value FROM problem_nodes WHERE node_name = "location" AND id_problem = p.id_problem) AS t_location, 
    (SELECT node_value FROM problem_nodes WHERE node_name = "department" AND id_problem = p.id_problem) AS t_department, 
    (SELECT node_value FROM problem_nodes WHERE node_name = "cc" AND id_problem = p.id_problem) AS t_cc, 
    (SELECT node_value FROM problem_nodes WHERE node_name = "status" AND id_problem = p.id_problem) AS t_status, 
    (SELECT node_value FROM problem_nodes WHERE node_name = "case_manager" AND id_problem = p.id_problem) AS t_case_manager, 
    (SELECT node_value FROM problem_nodes WHERE node_name = "ip" AND id_problem = p.id_problem) AS t_ip, 
    (SELECT node_value FROM problem_nodes WHERE node_name = "case_manager_eid" AND id_problem = p.id_problem) AS t_case_manager_eid, 
    id_problem, 
    id_problem_type, 
    eid_author, 
    title, 
    body, 
    date_created, 
    date_modified 
FROM 
    problems AS p 

私もproblem_nodes.node_name列がインデックス化されていない場合は、パフォーマンスの向上が表示されない可能性があることを言及する必要があります。

関連する問題