如何在使用内容提供商时进行GROUP BY?

时间:2017-08-08 16:34:04

标签: android sql group-by cursor android-contentprovider

我为我的应用程序创建了一个内容提供程序。为简单起见,我将举一个例子。我有一个表'OrderDetails'。

  1. 我有一个OrderId列。
  2. 我有一个列,列出了在OrderId中购买的不同产品类型的数量。
  3. 我有一个OrderDetailId,它是该表的主键。
  4. 下表:enter image description here

    我想写一下查询:SELECT OrderID, sum(quantity) FROM OrderDetails GROUP BY OrderID哪会返回:enter image description here

    但是,我尝试在我的内容提供程序的URI中插入我的GROUP BY子句但它不起作用,因此生成的查询变为:SELECT OrderID, sum(quantity) FROM OrderDetails返回此(所有内容的全部数量和最后一个的OrderId):enter image description here

    以下是获取光标并简单打印出刚刚创建的结果的方法:

    private void findQuantityByOrder(){
        Uri uri = DatabaseContract.CONTENT_URI_ORDER_DETAILS;
        String[] selection = new String[] {DatabaseContract.DatabaseOrderDetails.ORDER_ID,
                "sum("+ DatabaseContract.DatabaseOrderDetails.QUANTITY + ")"
                        +"GROUP BY(" + DatabaseContract.DatabaseOrderDetails.ORDER_ID + ")"};
        String projection = null;
        String sortBy = null;
        String[] args = null;
    
        Cursor cursor = getContentResolver().query(
                uri,
                selection,
                projection,
                args,
                sortBy);
    
        for (int i = 0; i < cursor.getCount(); i ++) {
            cursor.moveToPosition(i);
            int orderID = cursor.getInt(cursor.getColumnIndex("orderID"));
            int quantity = cursor.getInt(cursor.getColumnIndex("sum(quantity)"));
    
            System.out.println("orderId: " + orderID + ". Quanitity: " + quantity);
        }
    }
    

    它只打印出所有订单的总和,以及表格中的最后一个ID。

    我相信GROUP BY已被删除,不再受支持。有没有其他方法可以提供相同的结果?

    谢谢

3 个答案:

答案 0 :(得分:1)

  

我为我的应用程序创建了一个内容提供程序

除非您计划让多个应用都使用此数据,否则我不建议您实施ContentProvider

  

我相信GROUP BY已被删除且不再受支持

ContentProvider / ContentResolver协议一般不支持SQL,更不用说GROUP BY了。毕竟,不要求使用SQL数据库实现ContentProvider

  

还有其他方法可以提供相同的结果吗?

GROUP BY上实施ContentProvider,而不是在客户端上。 IOW,以与使用REST风格的Web服务相同的方式处理此问题,其中Web服务是实现SQL的Web服务,而不是Web服务的客户端。

例如,如果路径为Uri的{​​{1}}处理基本查询,/foo可能会实现/foo/summarySUM位。

  

我试图在我的内容提供商的URI中插入我的GROUP BY子句,但它不起作用

由于我们没有GROUP BY实施,我们无法对此发表评论。但请注意,ContentProvider不是您返回的内容,因此将其放入投影中将是一种非典型的选择。

答案 1 :(得分:0)

回答我自己的问题:

Stackoverflow上有答案 - Android: Distinct and GroupBy in ContentResolver 我会把这个问题留下来,因为有些想法已被纳入回复中。

虽然我觉得,如其他答案中所述,这应该在内容提供商本身中进行排序。但是,当您呼叫内容提供商时,可以快速解决问题:

在您的投影字符串中,您只需添加...

 String projection = COLUMN_NAME + "'a_condition' GROUP BY " + COLUMN_NAME" 

希望这有帮助

答案 2 :(得分:0)

不确定是否仍在寻找答案,但是使用Content Provider攻击GROUP BY的方法是在group by中嵌入URI子句作为查询参数,并读取该内容内容提供商的查询方法。

因此典型查询看起来像

Uri uri = DatabaseContract.CONTENT_URI_ORDER_DETAILS + "?groupBy=" + DatabaseContract.DatabaseOrderDetails.ORDER_ID;

整个事情看起来像这样:

private void findQuantityByOrder(){
    Uri uri = DatabaseContract.CONTENT_URI_ORDER_DETAILS + "?groupBy=" + DatabaseContract.DatabaseOrderDetails.ORDER_ID;
    String[] projection = new String[] {DatabaseContract.DatabaseOrderDetails.ORDER_ID,
            "sum("+ DatabaseContract.DatabaseOrderDetails.QUANTITY + ")"};
    String selection = null;
    String sortBy = null;
    String[] args = null;

    Cursor cursor = getContentResolver().query(
            uri,
            projection,
            selection,
            args,
            sortBy);

    for (int i = 0; i < cursor.getCount(); i ++) {
        cursor.moveToPosition(i);
        int orderID = cursor.getInt(cursor.getColumnIndex("orderID"));
        int quantity = cursor.getInt(cursor.getColumnIndex("sum(quantity)"));

        System.out.println("orderId: " + orderID + ". Quanitity: " + quantity);
    }
}

在您的内容提供商代码中,您可以像这样轻松地获得分组依据

String groupBy = uri.getQueryParameter("groupBy");

希望这对某人有帮助。