我想通过说我相信正确的方法来处理这个问题可能会重组数据库表但是
我在一个客户工作,他正在购买美国大部分高尔夫球场的数据库。由于他将定期收到卖家的更新,我保留了已发送的结构。 (令人讨厌的是:数据的骗子卖家承诺在他“必须改变现有记录的ID”时告诉我们。什么?你在销售数据然后改变之后的唯一ID?)
所以我有一张T恤表(一组孔作为序列播放);一张圆桌(一个发球台)和一张洞(每个洞的个人得分)。
在发球台中,这些玩偶正在存储par(目标得分),就像字段名Par_ 1,Par_2,Par_3到Par_18一样,具有INT值。因此,孔号是字段名称的一部分,并且根本不存储为值。
现在让我们说我需要查找你在特定回合中等于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;
所以我可以很容易地通过洞找到分数,但是因为洞数被嵌入到这样的字段名中,所以查找一个洞的标准将涉及一场噩梦。
我是否应该开始编写一些内容来将tee和hole导出到他们自己的表中?
我是否遗漏了一些令我惊讶的SQL功夫?
你有什么建议?
答案 0 :(得分:14)
我建议编写一个实用程序,将数据从供应商的格式转换为您的首选格式。您的实用程序将负责将PAR_18等解析为更易于管理的索引。当您从供应商处获得更新数据时,可以通过实用程序运行它以生成首选格式的更新数据。
答案 1 :(得分:3)
我认为你应该以正确的方式处理它。
有一张表格,从卖家的ID到您的ID(这样,如果他更改了一个,您只需要更改该表)。只需编写一些脚本来导入/更新他发送到您自己系统的任何数据。
它不应该花费你很长时间,并且它将节省大量时间在以后实际编写查询。
答案 2 :(得分:1)
Asaph的答案是最好的方法,但是如果你真的宁愿保留破碎的结构,请考虑使用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 ...
;
答案 3 :(得分:0)
由于字段名称是静态的(永远不会超过18个孔)并且孔的PAR总是3-5,因此您可以为包含每个Par_X列的WHERE的每个PAR创建一个视图/ SP它。当你第一次写这篇文章时,它会很痛苦,但你会完成,而且每次获得新数据都不需要不断重新格式化。
查看PAR 3:
SELECT *
FROM tees
WHERE
tees.Par_1 = 3
OR tees.Par_2 = 3
OR tees.Par_3 = 3
...etc
为PAR 3 PAR 4和PAR 5做3次,你就完成了。那么你可以根据洞的PAR来根据需要调用选择和轮数。关于这一点最好的部分是你可以在连接中使用视图或者你可以想到的任何其他东西,就像普通的表一样。
如果您采用SP路线,您可以接受PAR作为参数并且只写一次。但是在这种情况下可能存在与使用SP相关的一些性能问题,并且您可能无法在连接或其他任何内容中使用它。
答案 4 :(得分:0)
一种实现依赖方式,就是访问dbms的系统表,这应该允许将列名称作为值比列名更加接受。 虽然这会引起安全问题,但可以通过使用过程来克服这些问题,并限制对此过程的访问。