2017-02-09 46 views
0

我需要以下查詢的幫助。'在'Matrix中使用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 *此組件在該specific項目的電機中時(只有一個項目在查詢中)。

我有查詢返回結果爲靜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 

我不知道如何創建一個動態查詢未知的電機數量和未知的motor_ids 我不知道它畢竟可能。

+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

我需要類似的東西,但在一個查詢中(使用子查詢) - 它必須是一個主要的SELECT。原因:如果它可以工作,我可以將它提供給可以通過UI執行腳本的用戶,但只有一個選擇無權創建tmp表或變量。 – Matt

+0

@Matt你應該在你的問題中添加相當重要的信息。你不能在一個選擇中做到這一點,而不改變你如何存儲你的數據或在第二步轉移數據。 – iamdave

+0

好的,明白了。 – Matt