2017-02-09 5 views
0

私は次のクエリで助けが必要です。'SQLの行列で使用する

私は4つのテーブルがあります:私は行列を返すクエリを作成する必要が

+------------+------------+--------------+-----------------+ 
| project | motor | component | motor_component | 
+------------+------------+--------------+-----------------+ 
| project_id | motor_id | component_id | mc_id   | 
| name  | project_id | name   | motor_id  | 
|   | name  |    | component_id | 
+------------+------------+--------------+-----------------+ 

「のコンポーネントはモーターXで使用される」:行で

+----------------+---------+---------+---------+-----+---------+ 
| component.name | MOTOR 1 | MOTOR 2 | MOTOR 3 | ... | MOTOR X | 
+----------------+---------+---------+---------+-----+---------+ 
| Flange   |  1 |   |   |  |   | 
| Shaft   |   |  1 |   |  |   | 
+----------------+---------+---------+---------+-----+---------+ 

私は列にコンポーネント名と1を必要としますMOTOR *このコンポーネントが特定のプロジェクト用にこのモーターに入っているとき(クエリで1つのプロジェクトのみ)。

私は、静力学motor_id用とモータの静的量のために結果を返すクエリ持っている(と静的PROJECT_IDを、これは問題ではありません):私はのための動的なクエリを作成する方法がわからない

SELECT c.name 
     ,CASE WHEN EXISTS (SELECT i.name 
         FROM component i 
          JOIN motor_component_ i_mc 
           ON i.component_id = i_mc.component_id 
         WHERE i.component_id = c.component_id 
          AND i_mc.id_motor = 7 
         ) 
      THEN '1' 
      ELSE NULL 
      END AS 'MOTOR 1' 
     ,CASE WHEN EXISTS (SELECT i.name 
         FROM component i 
          JOIN motor_component_ i_mc 
           ON i.component_id = i_mc.component_id 
         WHERE i.component_id = c.component_id 
          AND i_mc.id_motor = 12 
         ) 
      THEN '1' 
      ELSE NULL 
      END AS 'MOTOR 2' 
FROM component c 
    JOIN motor_component mc 
     ON c.component_id = mc.component_id 
    JOIN motor m 
     ON mc.motor_id = m.motor_id 
    JOIN project p 
     ON m.project_id = p.project_id 
WHERE p.project_id = 30 

不明なモーター数量と不明なモーターID 結局はわかりません。

+0

何アプリケーションあなたは、このデータを報告するために使用していますか? – iamdave

+1

可能であれば、この種の変換をプレゼンテーション層で行うことをお勧めします。私はそれが常にオプションではないことを感謝します。コンポーネントの数には安全な上限がありますか? –

+0

'PIVOT'を使ってデータを回転させることができますが、モータの数は固定しなければなりません。任意の数の列を持つSQLクエリを書くことはできません。 –

答えて

1

動的SQLを使用して、pivotを作成することはできますが、それは非常にアドバイスされていません。これは、より良いプレゼンテーション層で処理されます。

if object_id('dbo.t') is not null 
drop table t; 

create table t(Motor int, Component nvarchar(50)); 
insert into t values(1,'Flange'),(2,'Shaft'); 

declare @cols as nvarchar(max), 
    @query as nvarchar(max); 

set @cols = stuff((select distinct ',' + quotename(Motor) 
      from t 
      for xml path(''), type 
      ).value('.', 'nvarchar(max)') 
     ,1,1,'') 

set @query = 'select Component, ' + @cols + ' from 
      (
       select Motor 
         ,Component 
         ,1 as Installed 
       from t 
      ) x 
      pivot 
      (
       sum(Installed) 
       for Motor in (' + @cols + ') 
      ) p ' 
      ; 


execute(@query); 

if object_id('dbo.t') is not null 
drop table t; 

出力:

+-----------+------+------+ 
| Component | 1 | 2 | 
+-----------+------+------+ 
| Flange | 1 | NULL | 
| Shaft  | NULL | 1 | 
+-----------+------+------+ 
+0

私はそのようなものが必要ですが、(サブクエリを使って)1つのクエリでは、1つのメインSELECTでなければなりません。理由:それがうまくいくならば、私はそれをUIでスクリプトを実行できるユーザーに与えることができますが、tmpテーブルまたは変数を作成するためのパーミッションのない選択は1つだけです。 – Matt

+0

@Mattあなたの質問にはかなり重要な情報を追加してください。データの保存方法を変更したり、2番目のステップでデータをピボットすることなく、1つの選択肢でこれを行うことはできません。 – iamdave

+0

OK、分かりました。 – Matt

関連する問題