Как получить случайный idrow из двух таблиц с разной вероятностью% от SQlite в Java-приложении? - PullRequest
0 голосов
/ 06 января 2019

Я пишу приложение в JavaFX с помощью Scene Builder. Моя база данных SQlite. Для просмотра и редактирования SQLite я использую DB Browser

У меня есть таблица "Карточки" и таблица "предложений" в одном файле базы данных

Table Cards

Table senteces

У меня есть кнопка «Случайный» и две текстовые арии. Когда я нажимаю на кнопку, метод вызывается. Метод берет случайный idrow из таблицы «Карты» и устанавливает текст из столбцов в textArias в моем приложении.

Я хочу получить шанс при нажатии на кнопку: 70% шанс выбрать случайного идро из таблицы «Карты» и 30% шанс выбрать случайного идро из таблицы «предложений».

Пример: если я нажму на кнопку 10 раз. Мои TextArias будут отображать текст из столбцов таблицы "Карты" - 7 раз

текст из столбцов таблицы "предложения" - 3 раза

Как выбрать случайного идроу с процентным шансом 70/30 из двух таблиц?

Класс, в котором я сохраняю запрос (этот запрос выбирает случайный idrow и предотвращает пустые строки):

package src.card;

public class PersistentQueries {


  private String sqlRandom = "SELECT * FROM Cards where rowid = (ABS(RANDOM()) % (SELECT (SELECT MAX(rowid) from Cards)+1)) or rowid = (SELECT MAX(rowid) FROM Cards) ORDER BY rowid LIMIT 1";


  public String getSqlRandom() {
   return sqlRandom;
  }

  public void setSqlRandom(String sqlRandom) {
   this.sqlRandom = sqlRandom;
  }
}

Класс QuestionController:

@FXML  private TextArea ta_questText, ta_answerText;
@FXML  private Button btnRand;

Cards cards = new Cards();
PersistentQueries pq = new PersistentQueries();

ResultSet rs = null;
PreparedStatement pst = null;

@FXML void randomCard(ActionEvent event) {

try {
  Connection conn = DbConnection.getConnection();
  pst = conn.prepareStatement(pq.getSqlRandom());

  rs = pst.executeQuery();
  while (rs.next()) {

    ta_questText.setText(rs.getString("question"));
    ta_answerText.setText(rs.getString("answer"));
  }

  pst.close();
  rs.close();
  conn.close();
    } catch (SQLException e) {
  e.printStackTrace();
   }
  }

EDIT:

Согласно ответу @MikeT я сделал специальный запрос и поместил его в один класс со всеми своими запросами:

public class PersistentQueries {

private String sqlRandomCat1 = "SELECT CASE WHEN ((abs(random()) % 10) + 1) > 7 THEN (SELECT 'category1' || rowid FROM category1 ORDER BY random() LIMIT 1) ELSE (SELECT 'sentences' || rowid FROM sentences ORDER BY random() LIMIT 1) END ";

public String getSqlRandomCat1() {
return sqlRandomCat1;
}

 public void setSqlRandomCat1(String sqlRandomCat1) {
this.sqlRandomCat1 = sqlRandomCat1;
 }

}

В моем QuestionController классе я создал объект этого класса с запросами:

PersistentQueries pq = new PersistentQueries();

, а затем создал метод, который будет брать текст из столбцов в таблицах и устанавливать этот текст в текстовые области:

@FXML void randomCard(ActionEvent event) {

try {
  Connection conn = DbConnection.getConnection();
  pst = conn.prepareStatement(pq.getSqlRandomCat1());

  rs = pst.executeQuery();
  while (rs.next()) {

    ta_questText.setText(rs.getString("question"));
    ta_answerText.setText(rs.getString("answer"));
  }

  conn.close();

   } catch (SQLException e) {
     e.printStackTrace();
    }
  }

Я также продублировал столбцы «вопрос» и «ответ» в таблице «предложений», потому что у них не было этих столбцов. Таким образом, эти столбцы являются просто повторяющимся текстом из столбца «предложение»

sentences table

Но после запуска приложения я получаю следующие ошибки:

java.sql.SQLException: no such column: 'question'
at org.sqlite.jdbc3.JDBC3ResultSet.findColumn(JDBC3ResultSet.java:48)
at org.sqlite.jdbc3.JDBC3ResultSet.getString(JDBC3ResultSet.java:443)
at src.card.QuestController.randomCard(QuestController.java:454)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at 
  ...

Есть идеи?

РЕДАКТИРОВАТЬ 2:

Что делать, если я буду использовать тот же запрос, что и раньше, чтобы сгенерировать случайного idrow из одной таблицы и создать такой метод:

  • генерирует случайный шанс

  • если шанс <70 - вызовите запрос, который возьмет строку произвольного идентификатора из таблицы «Карты» и примените текст из столбцов к моей текстовой области </p>

  • , если шанс> 70 и <100 - вызвать запрос, который будет извлекать случайного idrow из таблицы «предложений» и применить текст из столбцов к моей textArea </p>

Но я не знаю, как сделать этот метод.

Вы можете мне помочь?

Ответы [ 2 ]

0 голосов
/ 07 января 2019

РЕШЕНИЕ НАЙДЕНО!

Я создал сгенерированное случайное число, подобное этому, в методе:

int n = (int) (Math.random() * 100);

и я поставил условие:

if(n < 70) {
//70 % chance to set Text from Category 1
}

else if (n < 80) {
//30% chance to set Text from table "sentences"
}

Мой полный код выглядит так:

В классе, где я храню все запросы SQLite:

public class PersistentQueries {

private String sqlRandomCat1 = "SELECT * FROM Category1 where rowid = (ABS(RANDOM()) % (SELECT (SELECT MAX(rowid) from Category1)+1)) or rowid = (SELECT MAX(rowid) FROM Category1) ORDER BY rowid LIMIT 1";
private String sqlRandomSent = "SELECT * FROM sentences where rowid = (ABS(RANDOM()) % (SELECT (SELECT MAX(rowid) from sentences)+1)) or rowid = (SELECT MAX(rowid) FROM sentences) ORDER BY rowid LIMIT 1";

  public String getSqlRandomCat1() {return sqlRandomCat1;}

  public void setSqlRandomCat1(String sqlRandomCat1) {this.sqlRandomCat1 = sqlRandomCat1;}

  public String getSqlRandomSent() {return sqlRandomSent;}

  public void setSqlRandomSent(String sqlRandomSent) {this.sqlRandomSent = sqlRandomSent;}


}

Контроллер:

@FXML
  void randomCard(ActionEvent event) throws SQLException {

    int n = (int) (Math.random() * 100);
    if (n < 70) {
      Connection conn = DbConnection.getConnection();
      pst = conn.prepareStatement(pq.getSqlRandomCat1());

      rs = pst.executeQuery();
      while (rs.next()) {

        ta_questText.setText(rs.getString("question"));
        ta_answerText.setText(rs.getString("answer"));

      }
    } else if (n < 80) {
      ta_questText.setText("");
      Connection conn = DbConnection.getConnection();
      pst = conn.prepareStatement(pq.getSqlRandomSent());

      rs = pst.executeQuery();
      while (rs.next()) {

        ta_questText.setText("");
        ta_answerText.setText(rs.getString("sentence"));
      }

    }
  }
0 голосов
/ 06 января 2019

Вы можете использовать запрос, основанный на следующем: -

SELECT
    CASE
        WHEN ((abs(random()) % 10) + 1) > 7 THEN 
            // 70% chance
            (SELECT rowid FROM cards ORDER BY random() LIMIT 1)  
        ELSE 
            // 30% chance
            (SELECT rowid FROM sentences ORDER BY random() LIMIT 1) 
    END
;

Однако вы бы тогда не знали, из какой таблицы пришел rowid, поэтому, возможно, вы могли бы провести различие, используя 'c'||rowid вместе с 's'||rowid для различения таблиц.

...