2009-10-30 2 views
3

Я хочу предварить это тем, что я считаю, что правый ™ способ справиться с этим, вероятно, перестроить таблицы базы данных НОGolf SQL Проблема

У меня есть работа для клиента, где он покупает базу данных большинства поля для гольфа в США. Поскольку он будет периодически получать обновления от продавца, я сохранил структуру как отправленную. (Отвратительно в стороне: продавец данных о слонах обещает сообщить нам, когда он «должен изменить идентификатор существующей записи». Что? Вы продаете данные, а затем меняете уникальный идентификатор после?)

Итак, у меня есть таблица тройники (группы отверстий, играемые как последовательность); стол раундов (одна игра из тройника) и стол отверстий (индивидуальный подсчет для каждого отверстия).

В таблице тройников эти dolts сохраняют пар (целевую оценку) так же, как имя поля 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; 

Так что я могу легко посмотреть баллы по дыре, но смотреть вверх пар для отверстия будет включать в кошмар, так как число отверстие вкладывается в название поля, как это.

Должен ли я просто начать писать что-то, чтобы экспортировать парные тройники и отверстия в их собственный стол?

Я пропустил какой-то удивительный SQL-кунг-фу, который спасет меня?

Каков ваш совет?

+0

Сообщите нам, как вы * действительно * чувствуете. –

+6

Вы не должны ставить «Гольф» в любом названии здесь. Я думал, что вы запрашиваете сокращенный SQL-запрос. :-D – HalfBrian

+0

«Вы продаете данные, а затем меняете уникальный идентификатор?» Да, это происходит в реальном мире и является одним из преимуществ наличия надежного источника (вместо того, чтобы сворачивать ваши собственные идентификаторы), то есть вы платите кому-то за это. Рассмотрим книгу, выпущенную с дубликат ISBN: организация сортирует дубликат и уведомляет пользователей об изменении идентификатора. – onedaywhen

ответ

14

Я рекомендую написать утилиту, которая преобразует данные из формата поставщика в предпочтительный формат. Ваша утилита будет отвечать за разбор PAR_18 и тому подобное во что-то более управляемое, которое вы можете индексировать. Когда вы получаете обновленные данные от поставщика, вы запускаете его через свою утилиту для генерации обновленных данных в предпочтительном формате.

+4

... и перепродавать данные в скорректированной модели] :) –

+2

Если данные, которые у вас есть, не находятся в пригодном для использования формате, и вы предвидите новые данные, поступающие в плохом формате, напишите утилиту преобразования. – Nate

3

Я думаю, что вы, вероятно, должны справиться с ним правильно.

Имейте таблицу, которая отображает от идентификаторов продавца к вашим идентификаторам (таким образом, если он меняет один, все, что вам нужно сделать, это изменить эту таблицу). И просто напишите несколько сценариев для импорта/обновления любых данных, которые он отправляет вам в вашу собственную систему.

Это не займет у вас много времени, и это сэкономит много времени на самом деле написания запросов позже.

+0

Это действительно хорошая рекомендация, после нескольких лет работы над этим материалом я научился всегда сопоставлять уникальный идентификатор внешней системы с нашим уникальным идентификатором для каждой записи. Изменение сторонних/внешних систем так называемого «уникального идентификатора» происходит чаще, чем вы ожидали. – Jacob

0

Поскольку имена полей являются статическими (их никогда не будет больше 18 отверстий), а PAR дыры всегда равно 3-5, вы можете создать представление/SP для каждого PAR, который включал WHERE для каждого столбца Par_X в этом. Это будет боль в прикладе в первый раз, когда вы его напишете, но вы будете готовы и не будете постоянно переформатировать каждый раз, когда будете получать новые данные.

VIEW PAR 3:

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

ли, что в 3 раза для PAR 3 PAR 4 и 5 PAR и вы сделали. то вы можете вызывать selects и wheres по мере необходимости, основываясь на PAR дыры.Лучшая часть этого заключается в том, что вы можете использовать представление в соединении или что-нибудь еще, что вы можете себе представить, как обычную таблицу.

Если вы берете маршрут SP, вы можете принять PAR как параметр и только написать его один раз. Но в этом случае могут возникнуть некоторые проблемы с производительностью, связанные с использованием SP, и вы не сможете использовать его в соединениях или чем-то еще.

+0

Я восстановил это по запросу автора. Я не думаю, что он решает эту проблему, но, возможно, может привести к мысли о более эффективном решении в аналогичных терминах. –

0

Способ реализации, который должен был бы иметь доступ к системным таблицам dbms, это должно позволить accees именам столбцов в качестве значений raher, чем имена столбцов. Хотя это может привести к проблемам безопасности, это может быть преодолено, хотя использование процедуры и ограничение доступа к этой процедуре.

1

Ответ Асафа - лучший способ, но если вы действительно хотите сохранить сломанную структуру, изучите использование UNPIVOT и надейтесь, что она будет поддерживаться вашей СУБД. Что-то вроде:

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 ... 
; 
Смежные вопросы