Ruby on Rails: сложный расчетный запрос - PullRequest
0 голосов
/ 19 декабря 2011

В приложении ruby ​​on rails у меня есть таблица с именем test_details со следующими полями:

id,
profileId,
testName,
testId,
dateCovered,
levelCompleted,
userResult,
unit

здесь levelCompleted может иметь одно из пяти значений:

l1, l2, l3, l4, l5

я хочу создать отчет, чтобы найти количество каждого уровня на основе testName и его процент *

, например:

testID  ll       l2          l3        l4       l5
-------------------------------------------------------
test1   25(25%)  45(35.2%)   12(10%)   12(10%)  15(12%)
test2   25(25%)  45(35.2%)   12(10%)   12(10%)  15(12%)
test3   58(25%)  445(35.2%)  145(10%)  42(10%)  25(12%)

(Значения ипроценты не являются точными значениями)

как я могу сделать это в контроллере и просмотреть?

Мой код контроллера:

  @all_tests = TestDetails.count
  @test_details  = TestDetails.select("DISTINCT(testName)")
  puts(@test_details)
  @test_details.each do | test_details | 
    @test_name = test_details["testName"];
    @level1_total  = TestDetails.where("testName =? and levelCompleted =? and dateCovered is ?",test_details["testName"],1,nil).count
    @level1_total_percent = (@level1_total/@all_tests.to_f)*100

    @level2_total  = TestDetails.where("testName =? and levelCompleted =? and dateCovered is ?",test_details["testName"],2,nil).count
    @level2_total_percent = (@level2_total/@all_tests.to_f)*100

    @level3_total  = TestDetails.where("testName =? and levelCompleted =? and dateCovered is ?",test_details["testName"],3,nil).count
    @level3_total_percent = (@level3_total/@all_tests.to_f)*100

    @level4_total  = TestDetails.where("testName =? and levelCompleted =? and dateCovered is ?",test_details["testName"],4,nil).count
    @level4_total_percent = (@level4_total/@all_tests.to_f)*100

    @level5_total  = TestDetails.where("testName =? and levelCompleted =? and dateCovered is ?",test_details["testName"],5,nil).count
    @level5_total_percent = (@level5_total/@all_tests.to_f)*100

end

Ответы [ 2 ]

1 голос
/ 19 декабря 2011

Во-первых, то, как вы выполняете запросы к БД, совершенно неэффективно. Вы выполняете колоссальное количество (2 + 5 * количество различных testNames) запросов, чтобы это работало, каждый из них сканирует всю таблицу ! На большой таблице ваша БД наверняка захлебнется.

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

В сыром SQL то, что вы пытаетесь достичь, возможно в одном тривиальном запросе :

SELECT      testName, levelCompleted, COUNT(*) AS count
  FROM      test_details
  GROUP BY  testName, levelCompleted

# BTW, your field names don't follow rails convention...
# try to follow the conventions unless you have
# very good reasons not to do so.

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

testName | levelCompleted  | count
-----------------------------------
testone  |       1         |  10
testone  |       2         |  10
testone  |       3         |  15
testone  |       4         |  3
testone  |       5         |  2
testTWO  |       1         |  10
testTWO  |       2         |  15
testTWO  |       3         |  4

# and so on... there's two gotcha though: 
# - if there is no record for a particular 
#   level and testName, itwon't appear at all in this !
# - the order of the rows is not guaranteed, 
#   but you can enforce it with an ORDER clause

Тем не менее, в Rails вычисления могут оказаться немного хитрыми. У меня нет достаточно времени, чтобы развить это здесь, и я думаю, что это не помогло бы вам и не дать вам ответ «из коробки» ... Вы должны действительно углубиться в руководства по RoR, особенно о миграции , ассоциации и запросы .

Я остаюсь доступным, если у вас есть какие-либо вопросы.

0 голосов
/ 19 декабря 2011

Не ожидайте готового ответа в виде рабочей программы здесь.Вы не получите это.Вместо этого ожидайте предложений о том, как вы можете реализовать свои собственные и учиться.

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

Структура хэша может выглядеть следующим образом:

report = {
  test1 => {
    level1 => {
      total => "total", 
      percent => "percent"
    },

    level2 => {
      total => "total",
      percent => "percent"
    },

    ...    
  },

  test2 => {
    level1 => {
      total => "total",
      percent => "percent"
    }

    ...
  }
}

Почему бы неВы попробуете этот подход и вернетесь с кодом, если вы застряли?Мы постараемся помочь вам в рефакторинге и оптимизации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...