SQLite查询以选择匹配的行,然后选择ID最高的第二行

时间:2018-12-16 14:16:52

标签: sql sqlite android-sqlite

我的表格有4列:

这是我的数据库。

ID      SSID      BSSID         RSSI
1.      jbhd      ed:2d:5c      -60 
2.      ABCD      ab:cd:17      -68
3.      ijkl      cs:gb:d6      -75 
4.      vxfs      dc:5g:f4      -72
5.      cxzv      fg:4d:ac      -54
6.      ABCD      ab:cd:17      -68
7.      ertd      bv:we:12      -57
8.      erbc      gd:56:lt      -83

....
518.    ABCD      ab:cd:17      -68
519.    asfd      ag:4g:32      -60
520.    aasd      gd:5g:56      -79

我正在尝试编写一个查询数据库以返回特定记录和具有最高ID的2条下一条记录的函数。

到目前为止,我所做的是:

public Cursor get3records(String mac, int level){
    SQLiteDatabase db = this.getReadableDatabase();
    Cursor res = db.rawQuery("SELECT * from Scans_table st where ID >= ( select ID from Scans_table where BSSID =? AND RSSI =? ) order by st.ID asc limit 3 ", new String[] {mac, String.valueOf(level)});
    return res;
}

maclevel是决定我要从查询中获取哪些记录的参数。

例如,看看提供的示例数据。我想获取所有在ab:cd:17列中有BSSID和在-68列中有RSSI的记录(记录2、6、518)以及接下来的2个记录中,{ {1}}(记录3、4、7、8、519、520)。

问题是,此函数返回如下结果:

ID

我正在寻找的结果应该是这样的:

ID      SSID      BSSID         RSSI
2.      ABCD      ab:cd:17      -68
3.      ijkl      cs:gb:d6      -75 
4.      vxfs      dc:5g:f4      -72

3 个答案:

答案 0 :(得分:0)

如果id是连续的且没有间隔(如您的示例),则可以执行以下操作:

select st.*
from scans_table st join
     (select st2.id
      from scans_table st2
      where bssid = ? and rssi = ?
     ) ids
     on st.id in (ids.id, ids.id + 1, ids.id + 2);

如果ID不连续,这将变得更加棘手。最简单的方法可能是实现lag()

select *
from (select st.*,
             (select st2.bssid
              from scans_table st2
              where st2.id < st.id
              order by st2.id desc
              limit 1
             ) as prev_bssid,
             (select st2.rssi
              from scans_table st2
              where st2.id < st.id
              order by st2.id desc
              limit 1
             ) as prev_rssi,
             (select st2.bssid
              from scans_table st2
              where st2.id < st.id
              order by st2.id desc
              limit 1, 1
             ) as prev2_bssid,
             (select st2.rssi
              from scans_table st2
              where st2.id < st.id
              order by st2.id desc
              limit 1, 1
             ) as prev2_rssi
      from scans_table st
     ) st
where (bssid = ? and rssi = ?) or
      (prev_bssid = ? and prev_rssi = ?) or
      (prev2_bssid = ? and prev2_rssi = ?);

当然,如果您使用的是SQLite的最新版本,则可以使用窗口函数,这使此操作变得更加容易:

select *
from (select st.*,
             lag(bssid) over (order by id) as prev_bssid,
             lag(rssi) over (order by id) as prev_rssid,
             lag(bssid, 2) over (order by id) as prev2_bssid,
             lag(rssi, 2) over (order by id) as prev2_rssid
      from scans_table st
     ) st
where (bssid = ? and rssi = ?) or
      (prev_bssid = ? and prev_rssi = ?) or
      (prev2_bssid = ? and prev2_rssi = ?);

答案 1 :(得分:0)

<ListView.ItemContainerStyle>
        <Style TargetType="ListViewItem">
            <Setter Property="Margin" Value="0" />
            <Setter Property="Padding" Value="0" />
            <Setter Property="Height" Value="75" />
            <Setter Property="Width" Value="75" />
            <Setter Property="MinWidth" Value="75" />
            <Setter Property="MinHeight" Value="75" />
        </Style>
</ListView.ItemContainerStyle>

答案 2 :(得分:0)

我没有要提出的sql语句,但是有一个Java方法可以获取所需的结果。首先是获取符合条件的ID:

where BSSID =? AND RSSI =?

,然后为每个ID提取以下两个ID。
它将所有获取的ID包装在IN语句中,并执行最后的SELECT语句:

public Cursor get3records(String mac, int level){
    SQLiteDatabase db = this.getReadableDatabase();

    Cursor res = db.rawQuery("SELECT * from Scans_table st where BSSID = ? AND RSSI = ?", new String[] {mac, String.valueOf(level)});

    List<Integer> list = new ArrayList<>();

    if (res.moveToFirst()) {
        do {
            list.add(res.getInt(0));
        } while (res.moveToNext());
    }

    res.close();

    if (list.size() == 0)
        return null;

    List<Integer> all = new ArrayList<>(list);

    for (int id : list) {
        res  = db.rawQuery("SELECT id from Scans_table where id > ? ORDER BY id LIMIT 2", new String[] {String.valueOf(id)});

        if (res.moveToFirst()) {
            do {
                all.add(res.getInt(0));
            } while (res.moveToNext());
        }

        res.close();
    }

    StringBuilder sb = new StringBuilder("");
    for (int id : all) {
        sb.append(String.valueOf(id)).append(",");
    }
    String sqlIn = sb.toString();
    sqlIn = sqlIn.substring(0, sqlIn.length() - 1);

    return db.rawQuery("SELECT * from Scans_table where id IN (" + sqlIn + ") ORDER BY id", null);
}

如果只有一个sql语句可以产生所需的结果,则可能会更有效或更快速。
如果找不到任何内容,那么可以使用java作为解决方案。
PS 我希望我没有错字 ...

相关问题