2009-10-30 83 views
3

我想要說我認爲正確的™的方式來處理這前言這可能是重組數據庫表,但高爾夫SQL問題

我有一個客戶,他正在購買的大多數數據庫的一個作業美國的高爾夫球場。由於他會定期收到賣家的更新,所以我保留了發送的結構。 (骯髒的一邊:數據的蠢貨賣家承諾讓我們知道他什麼時候「必須更改現有記錄的ID」。什麼?您正在銷售數據,然後更改唯一ID後?)

所以我有一個表發球臺(按照順序排列的洞羣);一張發球臺(一個發球臺)和一張洞(每個洞個人得分)。

在tees表格中,這些玩家將場地名稱Par_ 1,Par_ 2,Par_ 3和Par_ 18以及INT值存儲在par(目標分數)中。所以孔號是字段名稱的一部分,並且根本不存儲爲值。

現在讓我們來說說,我需要查找在特定回合中對於洞數爲3的洞的所有得分的平均值。或者你所有的回合。

喜歡的東西

SELECT (SUM(holesPlayed.score)/COUNT(holesPlayed.score)) 
FROM holesPlayed, tees 
WHERE 
holesPlayed.round_id = 9 
AND tees.CourseTeeNumber = 'UT-94-1' 
AND tees.Par_x = 3; 

所以我可以很容易地查找得分的洞,但查找面值爲一孔,因爲孔數嵌入在這樣的字段名稱將涉及一場噩夢。

我是否應該開始寫一些東西,通過三通和空洞將它們導出到自己的表中?

我錯過了一些驚人的SQL功夫,會救我嗎?

您的建議是什麼?

+0

告訴我們您*真的*感受。 – 2009-10-30 22:00:41

+6

你不應該在這裏的任何標題「高爾夫」。我以爲你在問一個簡短的SQL查詢。 :-D – HalfBrian 2009-10-30 22:08:15

+0

「您正在銷售數據,然後更改唯一ID後?」是的,這發生在現實世界中,並且是擁有可信來源(而不是滾動自己的標識符)的優勢之一,即您付費爲您提供幫助。考慮使用重複ISBN發行的書:組織對重複進行排序並通知用戶標識符的變化。 – onedaywhen 2011-09-27 10:34:17

回答

14

我推薦編寫一個實用程序,將數據從供應商的格式轉換爲您的首選格式。您的實用程序將負責將PAR_18等解析爲您可以編入索引的更易於管理的內容。當您從供應商那裏獲得更新的數據時,您可以通過您的實用程序運行它,以您的首選格式生成更新的數據。

+4

...並考慮倒賣修正模型中的數據] :) – 2009-10-30 22:02:38

+2

如果數據不是以可用的格式,你預見到新的數據在惡劣的格式來寫一個轉換工具。 – Nate 2009-10-30 22:12:46

3

我想你可能應該處理它的Right™方式。

有一張表格,從賣家的ID映射到你的ID(這樣,如果他改變了一個,你所要做的就是改變該表)。只需編寫一些腳本來導入/更新他發送給自己系統的任何數據。

它不應該花費很長時間,而且在以後實際編寫查詢時會節省大量時間。

+0

這真的是一個很好的建議,經過多年的工作,我已經學會了將外部系統唯一標識符映射到我們自己的唯一標識符的每條記錄中。第三方/外部系統改變所謂的「唯一身份證」比您期望的更頻繁地發生。 – Jacob 2009-10-30 22:33:51

0

由於字段名稱是靜態的(永遠不會超過18個孔),並且洞的PAR總是3-5,所以可以爲每個PAR包含每個Par_X列的WHERE的每個PAR創建一個視圖/ SP在裏面。當你第一次寫它時,這將是一件痛苦的事情,但是你將會完成,並且每次獲得新數據時都不需要不斷重新格式化。

VIEW PAR 3:

SELECT * 
FROM tees 
WHERE 
    tees.Par_1 = 3 
OR tees.Par_2 = 3 
OR tees.Par_3 = 3 
...etc 

做的是3倍標準桿3杆4杆洞和五杆洞,你就大功告成了。那麼你可以根據洞的PAR,在你需要的時候調用選擇和輪。關於這一點最好的部分是,你可以在連接中使用視圖,或者像普通表一樣使用其他任何你能想到的東西。

如果走SP路線,你可以接受的PAR作爲參數,只寫一次。但是在這種情況下可能會有一些與使用SP相關的性能問題,並且您可能無法在連接或其他任何方面使用它。

+0

我通過作者的請求取消了這個功能。我認爲它不能解決眼前的問題,但也許可能導致在類似條款下思考更好的解決方案。 – 2009-10-30 22:47:40

0

的實現depenant方式,將訪問DBMS的系統表,這應該讓accees的列名比列名值raher。 雖然這會引發安全問題,但可以通過使用某個過程來克服這些問題,並限制對此過程的訪問。

1

亞薩的回答是最好的方式,但如果你真的寧願保持破壞的結構,考慮使用UNPIVOT,並希望它是由你的DBMS支持。例如:

SELECT (SUM(score)/COUNT(score)) AS avgScore 
    FROM holesPlayed 
    JOIN (
     SELECT * FROM Tees 
     UNPIVOT (Par FOR Par_N IN 
      (Par_1, Par_2, Par_3, Par_4, Par_5)) AS Ts 
     WHERE CourseTeeNumber = 'UT-94-1' 
) AS Ts 
    ON Ts.CourseTeeNumber = holesPlayed.CourseTeeNumber 
    WHERE 
    holesPlayed.round_id = 1 
    AND Ts.Par = 3 
    GROUP BY ... 
;