我的表格有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;
}
mac
和level
是决定我要从查询中获取哪些记录的参数。
例如,看看提供的示例数据。我想获取所有在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
答案 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 我希望我没有错字 ...