2012-02-07 39 views
4

編輯:更新了兩個表相互之間進行同步。這是唯一涉及的表格。簡單地說,我需要對所有獨特記錄進行計數並以2d格式顯示。如何實現查找表的兩列值範圍

我有光學鏡片的表,樣品,其中如下:

  Spherical|Cylindrical 
      --------------------- 
      0  | 0.5 
      0.25 | 0.75 
      0.25 | 0.5 
      0  | 0 
      0  | 0.25 
      0  | 0.5 
      0.25 | 0.75 
      0.25 | 0.5 
      0.5  | 0 
      0.75 | 0 
      0.75 | 0 
      0.5  | 0.25 
      0.5  | 0.75 
      0.75 | 0.25 
      0.5  | 0.75 
      0.75 | 0.75 
      0.75 | 0.5 
      0.75 | 0.5 

等等...

我想要顯示的每個鏡頭的計數的鳥瞰圖以這種方式在2d格式組合:

Spherical/Cylindrical|0|0.25|0.5|0.75|... upto 8 in steps of 0.25 
-----------------------------------------  
       0 |1| 1 | 2 | 1 | 
       0.25 |0| 0 | 2 | 2 | 
       0.5 |1| 2 | 0 | 2 | 
       0.75 |2| 1 | 2 | 1 | 
       ... 
       upto 30 in steps of 0.25 

如何在c#.net與SQL Server 2008中實現此?這將是最好的方法?

我有一對夫婦的想法:

  1. 使用一些特殊的查詢在運行時生成一個視圖和2D
  2. 格式化 創建二維表樣(按上述格式)和更新每次鏡頭表更新時, 都會計數。

請給我你的想法和建議。謝謝!

+0

我肯定會去的1(必須不斷更新數據意味着除非使用觸發器,否則它總是會過時的)。但是我很難理解數據實際來自哪裏。你可以顯示樣本數據,以及如何導出計數? – 2012-02-07 20:08:51

+0

我假設還有另外一張表,你遺漏了嗎?一個持有這些鏡頭的鏡頭數量。 – 2012-02-07 20:51:48

+0

@AaronBertrand我已經更新了兩個表,以便彼此同步。請看一看。謝謝! – mankand007 2012-02-08 02:40:49

回答

2

這裏是如何使視圖查詢示例:

--build table variable and sample data 
DECLARE @Optical table (Spherical numeric(4,2),Cylindrical numeric(4,2)) 
INSERT INTO @Optical VALUES ( 0, 0.5) 
INSERT INTO @Optical VALUES (0.25,0.75) 
INSERT INTO @Optical VALUES (1.25, 0.5) 
INSERT INTO @Optical VALUES (1.25, 0.5) 
INSERT INTO @Optical VALUES ( 0, 0) 

--query to use as a basis for the view 
;with AllSpherical AS --this recursive CTE builds the 121 rows for: 0.00 to 30.0 
(
    SELECT convert(numeric(4,2),0.0) AS Spherical 
    UNION ALL 
    SELECT convert(numeric(4,2),Spherical+0.25) 
     FROM AllSpherical 
    WHERE Spherical<=29.75 
) 
SELECT 
    s.Spherical 
     ,SUM(CASE WHEN o.Cylindrical=0.00 THEN 1 ELSE 0 END) AS c_000 
     ,SUM(CASE WHEN o.Cylindrical=0.25 THEN 1 ELSE 0 END) AS c_025 
     ,SUM(CASE WHEN o.Cylindrical=0.50 THEN 1 ELSE 0 END) AS c_050 
     ,SUM(CASE WHEN o.Cylindrical=0.75 THEN 1 ELSE 0 END) AS c_075 
     ,SUM(CASE WHEN o.Cylindrical=1.00 THEN 1 ELSE 0 END) AS c_100 
     ,SUM(CASE WHEN o.Cylindrical=1.25 THEN 1 ELSE 0 END) AS c_125 
     ,SUM(CASE WHEN o.Cylindrical=1.50 THEN 1 ELSE 0 END) AS c_150 
     ,SUM(CASE WHEN o.Cylindrical=1.75 THEN 1 ELSE 0 END) AS c_175 
     --... add a case for all columns 

    FROM AllSpherical    s 
     LEFT OUTER JOIN @Optical o ON s.Spherical=o.Spherical 
    GROUP BY s.Spherical 
    OPTION (MAXRECURSION 120) 

輸出:

Spherical c_000 c_025 c_050 c_075 c_100 c_125 c_150 c_175 
---------- ----- ----- ----- ----- ----- ----- ----- ----- 
0.00  1  0  1  0  0  0  0  0 
0.25  0  0  0  1  0  0  0  0 
0.50  0  0  0  0  0  0  0  0 
0.75  0  0  0  0  0  0  0  0 
1.00  0  0  0  0  0  0  0  0 
1.25  0  0  2  0  0  0  0  0 
1.50  0  0  0  0  0  0  0  0 
1.75  0  0  0  0  0  0  0  0 
2.00  0  0  0  0  0  0  0  0 
2.25  0  0  0  0  0  0  0  0 
... 

(121 row(s) affected) 

您可以使用此查詢構建一個傳統的觀點,如果你更新遠遠超過原始數據你會閱讀這個觀點。這將是你的選擇1

如果你計劃閱讀這個視圖比你更新原始數據更多考慮持續觀看:Improving Performance with SQL Server 2005 Indexed ViewsCreating Indexed Views。這基本上實現了視圖,當你插入/更新/刪除底層表時,視圖的存儲數據更新很像自動系統級觸發器保持同步。這將是你的選擇2,但系統會做所有保持同步的「硬」工作。

+0

非常感謝!看起來這是我需要的。我需要顯示這個視圖作爲默認頁面,所以我想我應該選擇2.我是一個完整的新手.NET和sqls ..(我來自大型機/ cobol試圖我的手在其他'真正的'編程語言)..我會試試這個並更新你。非常感謝! – mankand007 2012-02-08 02:51:42

+0

我試過了,它的工作完美!太感謝了! – mankand007 2012-02-10 04:58:21

2

借用KM的表變量,這裏是另一種使用PIVOT並避免使用33 SUM(CASE...)表達式的方法。

DECLARE @Optical TABLE (Spherical DECIMAL(4,2), Cylindrical DECIMAL(4,2)); 

INSERT INTO @Optical VALUES ( 0, 0.5); 
INSERT INTO @Optical VALUES (0.25, 0.75); 
INSERT INTO @Optical VALUES (1.25, 0.5); 
INSERT INTO @Optical VALUES (1.25, 0.5); 
INSERT INTO @Optical VALUES ( 0, 0); 

;WITH x AS 
(
    SELECT TOP (33) [row] = (ROW_NUMBER() 
     OVER (ORDER BY [object_id])-1)*0.25 
     FROM sys.objects ORDER BY [row] 
), y AS 
(
    SELECT Spherical = x.[row], o.Cylindrical 
     FROM x 
     LEFT OUTER JOIN @Optical AS o 
     ON x.[row] = o.Spherical 
) 
SELECT pvt.* FROM y 
PIVOT (COUNT(y.Cylindrical) FOR y.Cylindrical IN 
(
    [0.00],[0.25],[0.50],[0.75],[1.00],[1.25],[1.50],[1.75],[2.00],[2.25],[2.50],[2.75], 
    [3.00],[3.25],[3.50],[3.75],[4.00],[4.25],[4.50],[4.75],[5.00],[5.25],[5.50],[5.75], 
    [6.00],[6.25],[6.50],[6.75],[7.00],[7.25],[7.50],[7.75],[8.00] 
)) AS pvt 
ORDER BY pvt.Spherical; 

現在,你可能在想,我不想在PIVOT部分輸入了所有這些值,但你可以很快生成這些:

DECLARE @sql NVARCHAR(MAX)= N''; 

;WITH x AS 
(
    SELECT TOP (33) [row] = (ROW_NUMBER() 
     OVER (ORDER BY [object_id])-1)*0.25 
     FROM sys.objects ORDER BY [row] 
) 
SELECT @sql = @sql + ',[' + RTRIM(CONVERT(DECIMAL(4,2), [row])) + ']' FROM x; 

SET @sql = STUFF(@sql, 1, 1, ''); 

PRINT @sql; 
+0

對於動態SQL,肯定爲+1。 – 2012-02-08 21:08:27

+1

OP只需要33列,最多8步0.25',這比你的語句少得多:'避免了121個SUM(CASE ...)表達式。' – 2012-02-09 13:58:55

+0

哎呀,我認爲它是兩邊的30。 – 2012-02-09 14:01:39