2009-10-30 44 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 ... 
;