【问题标题】:Anyway to change row number in SQLITE rawquery?无论如何要更改 SQLITE rawquery 中的行号?
【发布时间】:2012-05-15 12:26:31
【问题描述】:

我设置了以下光标来填充一个包含用户付款历史记录的对话框

Cursor PaymentsCursor = db.getReadableDatabase().rawQuery(
                "SELECT _id, Date, Payment FROM tblPaymentHistory WHERE DebtName = '"
                        + debtname + "'" + "ORDER BY _id ASC", null);
        SimpleCursorAdapter HistoryAdapter = new SimpleCursorAdapter(this,
                R.layout.paymenthistoryrow, PaymentsCursor, from, to);

问题在于,如果存在不止一种类型的债务,并且每笔债务的付款都乱序进行,那么当付款历史记录返回结果时,它会以乱序行号的形式返回,例如1、2、6、7、9、12等我知道它正在从数据库中提取 _id(唯一键),但是有没有办法重新设置或更改查询中的行号,以便每个结果返回为“1、2、3、4、5 等" 不考虑原始 ID?

我认为 ORDER BY _id 甚至 ORDER BY Date ASC 可以解决这个问题,但它没有。

我在数据库中的行看起来像这样:

1,测试,2012 年 4 月 13 日,250
2,测试,2012 年 4 月 13 日,300
3,测试,2012 年 4 月 14 日,222
4, TEST2, 4/14/2012, 500
5,测试,2012 年 4 月 15 日,600

当用户单击“TEST”的历史记录时,它会返回为 1、2、3、5... 如果他们拉出“TEST2”的历史记录,它会显示为“4”,我正在尝试得到它,所以 TEST 显示“1,2,3,4”,TEST2 显示“1”

该死,我无法回答自己的答案,但这是我最终要做的:

谢谢各位。我找到了一个修改视图的替代选项,因此不必触摸 SqLite db。这是我找到的链接Modifying SimpleCursorAdapter's data

结果如下:

PaymentsCursor = db.getReadableDatabase().rawQuery(
            " SELECT _id, Date, Payment FROM tblPaymentHistory WHERE DebtName = '"
                    + debtname + "'" + "ORDER BY _id ASC", null);

    String[] from = new String[] { DbAdapter.KEY_HISTORY_ID,
            DbAdapter.HISTORY_DATE, DbAdapter.HISTORY_PAYMENT };

    int[] to = new int[] { R.id.PAYMENTNO, R.id.PAYMENTDATE,
            R.id.PAYMENTAMOUNT };

    SimpleCursorAdapter HistoryAdapter = new SimpleCursorAdapter(this,
            R.layout.paymenthistoryrow, PaymentsCursor, from, to);

    HistoryAdapter.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
        @Override
        public boolean setViewValue(View view, Cursor cursor, int column) {
            if (column == 0) { // let's suppose that the column 0 is the
                                // date

                TextView tv = (TextView) view;
                String rownum = String.valueOf(cursor.getPosition() + 1);
                // here you use SimpleDateFormat to bla blah blah
                tv.setText(rownum);

                return true;
            }
            return false;
        }
    });

    paymenthistory.setAdapter(HistoryAdapter);

这可能不是最迷人的方式,但现在每次窗口出现历史记录时,它都使用行号(加一)来指示它是哪个#。 谢谢大家!

【问题讨论】:

  • 你为什么不拿你从Cursor#getPosition()得到的号码
  • 永远不要将值与原始查询字符串连接并执行它。 en.wikipedia.org/wiki/SQL_injection
  • @AustynMahoney 你是说把它改成类似这样的东西: PaymentsCursor = db.getReadableDatabase().rawQuery(" SELECT _id, Date, Payment FROM tblPaymentHistory WHERE DebtName = ?"+ "ORDER BY _id ASC ", 新字符串 [] { 债务名称 }); dang 我无法将其正确格式化为代码。对不起

标签: android sqlite cursor


【解决方案1】:

这是获取“重新基于”的 ID 的一种方法。在此示例中,“新 ID”基于 grade(即您的案例中的“旧 ID”):

.headers on

create table foo (name text, grade int);

insert into foo values ('Joe', 45);
insert into foo values ('Anna', 98);
insert into foo values ('Julie', 78);

select name, 
       grade, 
       (select count(*) from foo t1 where t1.grade>=t2.grade) as rank  
from foo t2;

select name, 
       grade, 
       (select count(*) from foo t1 where t1.grade>=t2.grade) as rank  
from foo t2
order by rank;

将它保存为 foo.sql,我得到了这个:

[someone@somewhere tmp]$ sqlite3 < foo.sql 
name|grade|rank
Joe|45|3
Anna|98|1
Julie|78|2
name|grade|rank
Anna|98|1
Julie|78|2
Joe|45|3

【讨论】:

    【解决方案2】:

    我已经对@sixfeetsix 的回答进行了一些尝试,因为它没有给出 1,2,3,4,.. 编号以及您可能需要放入更多子查询的 WHERE(也许不是,但是,我'不擅长查询):

    SELECT ( 
               SELECT count( * ) + 1
                 FROM  ( 
                       SELECT *
                         FROM tblPaymentHistory 
                        WHERE DebtName = ? 
                   ) 
                   AS t1
                WHERE t1._id < t2._id 
           ) 
           AS _id,
           Date,
           Payment
      FROM tblPaymentHistory AS t2
     WHERE DebtName = ?
     ORDER BY _id;
    

    放入 java String 并留下? 以获得转义值(注入安全):

    Cursor PaymentsCursor = db.getReadableDatabase().rawQuery(
                    "...WHERE DebtName=? .. WHERE DebtName=? .. ", new String[]{ debtname, debtname }); 
            SimpleCursorAdapter HistoryAdapter = new SimpleCursorAdapter(this,
                    R.layout.paymenthistoryrow, PaymentsCursor, from, to);
    

    【讨论】:

      【解决方案3】:

      经过长时间的研究,这个查询对我有用...

      我得出的经验结果:

      1)您还需要在子查询中定义 where 条件。 2)如果在关系运算符中比较的 ids (t2._id 3)关于 orderby 条件,您必须根据您的选择或需要来决定。

      SELECT 
      (SELECT COUNT(*) FROM table t2 WHERE t2._id <= t1._id AND t2.Recipe_id = 2) AS RowNumber,_id,Recipe_id,col2,col3,col4
      FROM table t1
      WHERE Recipe_id = 2
      ORDER BY _id
      

      它是如何工作的:-

      假设我们在某个表 t 中有一系列主键 1,2,3,4,5,6

      现在我们使用表 t1 和表 t2 创建它的两个别名

      Now both have same sequence table t1 -> 11,12,13,14,15,16
                                  table t2 -> 11,12,13,14,15,16
      

      现在这个条件( WHERE t2._id &lt;= t1._id ) 将 t2 的第一个主键“11”与 t2 as 11=11 的第一个主键“11”将 return count() 仅存在一行,因此我们 get "1" in row number..

      *** remember for every row in Outer query the sub-query is executed ***
      

      因此now outer query is at row second having primary key "12"

      现在它将again compare the ( WHERE t2._id &lt;= t1._id ) 这次again t2._id contains "11"t1._id contains "12"..

      很清楚,它会返回 TWO rows are there,它的 ids &lt;= 12 是 11 和 12

      这样它将生成所需的序列............

      这是一个生成序列的简单技巧..实际上看起来并不简单,但当你深入了解它时真的很简单..

      我不是专家,但这是我所理解的.. 希望解释有所帮助...

      由于网上有各种解决方案或相同的解决方案,但没有解释..

      :)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-05-16
        • 2016-08-17
        • 2016-02-04
        • 2020-06-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-02
        相关资源
        最近更新 更多