将SQLite嵌套查询转换为解析查询

时间:2014-07-11 03:37:39

标签: android parse-platform android-sqlite

对光标采用以下where子句:

whereClause = DBHelper.SCHEDULE_DAY + " = '" + dayOfTheWeek + "' AND "
                      + DBHelper.SCHEDULE_STARTTIME + " = (SELECT " + DBHelper.SCHEDULE_STARTTIME
                      + " FROM " + DBHelper.TABLE_SCHEDULE + " WHERE " + DBHelper.SCHEDULE_DAY
                      + " = '" + dayOfTheWeek + "' AND " + DBHelper.SCHEDULE_STARTTIME + " < "
                      + (currenttime - 100)  + " ORDER BY "
                      + DBHelper.SCHEDULE_STARTTIME + " DESC LIMIT 1)";

用SQL语法编写的内容是:

  

SELECT className FROM SCHEDULE WHERE day =&#34; Tuesday&#34; AND startTime =   (SELECT startTime FROM SCHEDULE WHERE day =&#34; Tuesday&#34; AND startTime&lt;   1200 ORDER BY startTime DESC LIMIT 1);

是否可能在Parse Queries中嵌套参数?使用LocalData存储功能,我想删除我的SQLite数据库,转而使用LocalDatastore,因为我已经将它用于临时缓存。也许我已经过度思考从SQLite到Parse的翻译,但这是我到目前为止所提出的:

ParseQuery<ParseObject> query = ParseQuery.getQuery("classes");
    query.whereEqualTo("day", dayOfTheWeek);
    // What to add in here for time?
    query.fromLocalDatastore();
    query.findInBackground(new FindCallback<ParseObject>() {
    public void done(List<ParseObject> classList, ParseException e) {
        if (e == null) {
           //Do something with results
        } else {
           // Failed
        }
    }
});

类完全持续一个小时,因此当前时间为-100(IE如果它是8AM,则查找从0700开始或之前的类(0800-100)。答案是复合Parse查询,例如以下:

ParseQuery<ParseObject> startHour = ParseQuery.getQuery("classes");
startHour.whereEqualTo("day", dayOfTheWeek);
query.whereLessThan("startHour", currenttime -100);
query.addDescendingOrder("startHour");
query.setLimit(1);

List<ParseQuery<ParseObject>> queries = new ArrayList<ParseQuery<ParseObject>>();
queries.add(startHour);

ParseQuery<ParseObject> mainQuery = ParseQuery.or(queries);
mainQuery.whereEqualTo("day", dayOfTheWeek);
mainQuery.findInBackground(new FindCallback<ParseObject>() {
  public void done(List<ParseObject> results, ParseException e) {
    // result is the classes that start at or before the hour found
  }
});

非常感谢StackOverflow社区提供的所有帮助!

更新:

我设法使用两个parseQueries解决了这个问题:

ParseQuery<ParseObject> startHour = ParseQuery.getQuery("schedule");
    startHour.whereEqualTo("day", "Thursday");
    startHour.whereLessThan("startHour", (currenttime - 100) / 100 * 100);
    startHour.orderByDescending("startHour");
    startHour.fromPin("schedule");
    startHour.setLimit(1);
    startHour.fromLocalDatastore();
    startHour.findInBackground(new FindCallback<ParseObject>() {
      public void done(List<ParseObject> results, ParseException e) {
        // result is the classes that start at or before the hour found
        for (ParseObject object : results) {
          time = object.getInt("startHour");
        }

        // Toast.makeText(Dialog_Checkin.this, "time query: " +
        // String.valueOf(time),
        // Toast.LENGTH_LONG).show();
      }
    });

    ParseQuery<ParseObject> mainQuery = ParseQuery.getQuery("schedule");

    mainQuery.whereEqualTo("day", "Thursday");
    mainQuery.fromPin("schedule");
    mainQuery.whereGreaterThan("startHour", time - 5);
    mainQuery.whereLessThan("startHour", time + 5);
    // mainQuery.whereEqualTo("startHour", 1930);
    mainQuery.fromLocalDatastore();
    mainQuery.findInBackground(new FindCallback<ParseObject>() {
      public void done(List<ParseObject> results, ParseException e) {
        // result is the classes that start at or before the hour found
        if (e == null) {
          Toast.makeText(Dialog_Checkin.this, "array values: " + String.valueOf(results.size()),
                          Toast.LENGTH_LONG).show();
          for (ParseObject object : results) {
            Toast.makeText(Dialog_Checkin.this, "array values: " + object.getString("class"),
                            Toast.LENGTH_LONG).show();
          }
        } else {
          Toast.makeText(Dialog_Checkin.this, e.getMessage(), Toast.LENGTH_LONG).show();
        }

        // Toast.makeText(Dialog_Checkin.this, "array values: " +
        // String.valueOf(results.size()),
        // Toast.LENGTH_LONG).show();
      }
    });
然而,我似乎发现了一个问题。如果我在第二个查询中添加约束

  

mainQuery.whereEqualTo(&#34; startHour&#34;,time);

返回0结果。如果我改变添加以下两个约束,它可以工作:

mainQuery.whereGreaterThan("startHour", time-5);
mainQuery.whereLessThan("startHour", time+5);

那么为什么如果我做GT和LT,它有效,但不等于?我在解析网站上发布了这个错误,这是我的数据存档的屏幕截图,显示了我期望返回的两个条目: enter image description here

2 个答案:

答案 0 :(得分:0)

所以我想出了部分问题,尽管还有一个bug。运行两个“findInBackground”操作似乎存在计时问题,其中第二个查询实际上在第一个查询期间或之前运行。当我尝试烘烤“时间-5”时,这很明显,我会得到一个弹出窗口,表示“-5”,而不是4位数时间,表示时间变量尚未从第一个查询中设置。

我最终通过将第一个查询更改为常规查询(ParseQuery.find())来解决该问题。这始终给了我第二次查询所需的时间值。

似乎仍然存在使用“whereEqualTo”不止一次的问题,所以我不得不使用GreaterThan和LessThan子句来解决这个问题。下面是我的代码,我想要它

ParseQuery<ParseObject> startHour = ParseQuery.getQuery("schedule");
    startHour.whereEqualTo("day", dayOfTheWeek);
    startHour.whereLessThan("startHour", (currenttime - 100));
    startHour.orderByDescending("startHour");
    startHour.fromPin("schedule");
    startHour.setLimit(1);
    startHour.fromLocalDatastore();
    startHour.clearCachedResult();
    List<ParseObject> results;
    try {
      results = startHour.find();
      ParseObject result = results.get(0);
      Toast.makeText(Dialog_Checkin.this, String.valueOf(result.getInt("startHour")),
                      Toast.LENGTH_LONG).show();
      timeT = result.getInt("startHour");
    } catch (ParseException e1) {
      // TODO Auto-generated catch block
      e1.printStackTrace();
    }

    ParseQuery<ParseObject> mainQuery = ParseQuery.getQuery("schedule");

    mainQuery.whereEqualTo("day", dayOfTheWeek);
    mainQuery.fromPin("schedule");

    mainQuery.whereGreaterThan("startHour", timeT - 5);

    mainQuery.whereLessThan("startHour", timeT + 5);
    // mainQuery.whereEqualTo("startHour", timeT); //This doesn't work...duhh
    mainQuery.fromLocalDatastore();
    mainQuery.findInBackground(new FindCallback<ParseObject>() {
      public void done(List<ParseObject> results, ParseException e) {
        // result is the classes that start at or before the hour found
        if (e == null) {

          for (ParseObject object : results) {
            Toast.makeText(Dialog_Checkin.this, "array values: " + object.getString("class"),
                            Toast.LENGTH_LONG).show();
          }
        } else {
          Toast.makeText(Dialog_Checkin.this, e.getMessage(), Toast.LENGTH_LONG).show();
        }
      }
    });

答案 1 :(得分:0)

这是一个有效的错误,并已在Facebook上解决 https://developers.facebook.com/bugs/335038033327436/