2015-06-02 5 views
0

У меня есть следующие проблемы: У меня есть таблица под названием строгания имеет следующие поля:Android союз запрос

idplaning, month, year, shop, target, sales 

так таблица будет содержать информацию, как это (не обращая внимания на idplaning):

month year shop  target sales 
------------------------------------------- 
    1  2014 ShopName1 3534 122 
    2  2014 ShopName1 2323 111 
    ... 
    12 2014 ShopName1 7865 328 
    1  2014 ShopName2 4544 544 
    2  2014 ShopName2 5675 642 
    ... 
    12 2014 ShopName2 4623 323 
    ... 
    1  2015 ShopName1 3534 122 
    2  2015 ShopName1 2323 111 
    ... 
    12 2015 ShopName1 7865 328 
    ... and so on 

в основном, таблица содержит ежемесячные цели и продаж для каждого магазина

мне нужно отобразить в Listview что-то вроде этого:

shop   Ianuary February March ... November December 
---------------------------------------------------------- 
ShopName1  3534 2323  235  3545  3355 
... 
ShopNamex  1527 7815  631  556  2754 

для того, чтобы сделать это (в простом SQL) я могу сделать союз, как это:

select shop, sum(Ian), sum(Feb),sum(Mar), sum(Apr), sum(Mai), sum(Iun), sum(Iul), sum(Aug), sum(Sep), sum(Oct), sum(Noi), sum(Decu) from 
(
    select shop,target as Ian, 0 as Feb, 0 as Mar, 0 as Apr, 0 as Mai, 0 as Iun, 0 as Iul, 0 as Aug, 0 as Sep, 0 as Oct, 0 as Noi, 0 as Decu from planing where year=2015 and month=1 
    union 
    ... 
    select shop,0 as Ian, 0 as Feb, 0 as Mar, 0 as Apr, 0 as Mai, 0 as Iun, 0 as Iul, 0 as Aug, 0 as Sep, 0 as Oct, 0 as Noi, target as Decu from planing where year=2015 and month=12 
) as tbl 
group by shop 

Теперь моя проблема заключается : как я могу это сделать, используя SQLite Database ContentProvider в Android с подход к поиску? У меня уже есть контент-провайдер, построенный для различных регулярных операций БД, и я использую запроса подход (вместо rawquery)

Поэтому я получить регулярный курсор (на мой строгания стол), как это:

String[] col = {MyFirstProvider.RSLDTL_ID_ID,MyFirstProvider.RSLDTL_SHOP, MyFirstProvider.RSLDTL_MONTH, MyFirstProvider.RSLDTL_TARGET, MyFirstProvider.RSLDTL_SALES}; 
String where = "year=2015"; 
Cursor cur = getActivity().getContentResolver().query(MyFirstProvider.CONTENT_URI_RSLDTL, col, where, null, null); 

моей проблема: Как я могу получить курсор на мой запрос UNION-сгруппированного, используя подход запроса (а не rawquery)

Пожалуйста, ответьте на код. Благодарю вас

EDIT Мой ContentProvider выглядит следующим образом:

общественный класс MyFirstProvider расширяет ContentProvider {

static final int DATABASE_VERSION = 7; 
private SQLiteDatabase db; 
static final String DATABASE_NAME = "myxdb.db"; 
public static final String TABLE_PLANING = "planing"; 
... 
static final String URLX = "content://" + PROVIDER_NAME + "/planing"; 
... 
public static final Uri CONTENT_URI_PLANING = Uri.parse(URLX); 
... 
static final int uriCode = 1; // some table 
static final int uriCode52 = 53; // planing 
static final int uriCode53 = 54; // planing 

static final UriMatcher uriMatcher; 
private static HashMap<String, String> values; 
static { 
    uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); 
    uriMatcher.addURI(PROVIDER_NAME, "planing", uriCode52); 
    uriMatcher.addURI(PROVIDER_NAME, "planing/*", uriCode53); 
    ... 
} 

.... 

@Override 
    public Cursor query(Uri uri, String[] projection, String where, String[] selectionArgs, String sortOrder) { 
     SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); 
     Cursor c; 
     switch (uriMatcher.match(uri)) { 
      case uriCode: 
       qb.setTables(TABLE_NAME); 
       qb.setProjectionMap(values); 
       c = qb.query(db, projection, where, selectionArgs, null,null, sortOrder); 
       break; 
      ... 
      default: 
      throw new IllegalArgumentException("(qry)Unsupported URI: " + uri); 
    } 
    if (c != null){ 
     c.setNotificationUri(getContext().getContentResolver(), uri); 
    } 
    return c; 
} 

Так как же я могу осуществить свою идею в моем выше подходе? Я имею в виду, как объявить uriCode для моего объединенного сложного запроса?

+0

Привет, rawQuery, требуется два параметра один для вашего сложного запроса, а другой - аргумент. создать свой собственный пользовательский запрос, который вы продемонстрируете выше? И передайте параметр. http://stackoverflow.com/questions/16136688/sqlite-select-query-with-rawquery-at-android. – mcd

+0

Пожалуйста, это не моя работа, чтобы добавить запрос diy. – mcd

+0

Я действительно думаю, что вы пропустили мой вопрос ... Если вы посмотрите на него снова, вы заметите, что у меня уже есть код для получения курсора для регулярного запроса (даже с использованием предложения where). Так что это не моя проблема. Также использование rawquery также не является проблемой. Моя проблема заключается в том, как реализовать курсор, используя подход 'query' для UNION-ed сгруппированного оператора select. Я вставил над скелетом моего ContentProvider, чтобы вы или кто-либо другой, кто хочет мне помочь, могли указать, куда добавить и что добавить. Я нигде не нашел примеров для UNION без rawQuery. – user1137313

ответ

0

Использовать rawquery в классе поставщика контента, где вы переопределяете метод запроса, передать необходимый столбец в методе запроса с помощью uri. , а в классе провайдеров соответствует соответствующий uri и выполнить ваш метод необработанных запросов, у вас уже есть объект db. .

getActivity() getContentResolver() запроса (MyFirstProvider.CONTENT_URI_RSLDTL, Col, где, NULL, NULL).

где вы можете получить col и где в параметре переопределять параметры запроса.

public class ExampleProvider extends ContentProvider { 
.... 
    public Cursor query(
      Uri uri, 
      String[] projection, 
      String selection, 
      String[] selectionArgs, 
      String sortOrder) { ... 
      /* 
      * Choose the table to query and a sort order based on the code returned for the incoming 
      * URI. Here, too, only the statements for table 3 are shown. 
      */ 
      switch (sUriMatcher.match(uri)) { 

        break; 

       default: 
       ... 
        // If the URI is not recognized, you should do some error handling here. 
      } 
      /* 
     * Gets a writeable database. This will trigger its creation if it doesn't already exist. 
     * 
     */ 
     db = mOpenHelper.getWritableDatabase(); 
     //execute raw query 
     db.rawQuery(...); 

     } 
+0

Если я это сделаю, я могу получить доступ к курсору, как обычный простой курсор? Как включить в rawquery предложение 'where' и предложение' order by', которое будет выведено из подхода запроса? Также как я объявляю uri для моего uriMatcher? – user1137313

+0

Я сделаю редактирование на мой вопрос, чтобы описать мой текущий подход к ContentProvider. Пожалуйста, проверьте это и соответствующим образом обновите свой ответ – user1137313

+0

, или вы можете использовать метод buildUnionQuery SQLiteQueryBuilder – mcd

0

Я не нашел способ использовать query вместо rawquery, когда вы хотите сделать запрос UNION.

Я понял, что в настоящее время этого не существует из-за того, что класс SQLiteQueryBuilder содержит методы для создания запроса UNION, но он не содержит никакого способа его выполнения, и я не ожидал бы найти это где-нибудь еще.

Более конкретно, если вы посмотрите на SQLiteQueryBuilder классе, вы обнаружите, что buildUnionQuery метод возвращает String и нет query метода, который принимает пользовательскую строку запроса в качестве параметра.

Тем не менее, решение, которое я принял в моем коде это:

Внутри вашего переключателя заявление query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) ...

SQLiteQueryBuilder builder = new SQLiteQueryBuilder(); 
builder.setTables(TABLE_NAME); 
HashSet<String> columnsPresentInTable = new HashSet<>(<columns in your table>); 
String firstProjection = "shop, target as Ian, 0 as Feb, 0 as Mar, 0 as Apr, 0 as Mai, 0 as Iun, 0 as Iul, 0 as Aug, 0 as Sep, 0 as Oct, 0 as Noi, 0 as Decu"; 
String firstSelectSubQuery = builder.buildUnionSubQuery(
     null, 
     firstProjection, 
     columnsPresentInTable, 
     0, 
     getType(uri), 
     selection, 
     new String[]{ 
      String.valueOf(2015), 
      String.valueOf(1) 
     }, 
     null 
); 
[...] 
String lastProjection = "shop, 0 as Ian, 0 as Feb, 0 as Mar, 0 as Apr, 0 as Mai, 0 as Iun, 0 as Iul, 0 as Aug, 0 as Sep, 0 as Oct, 0 as Noi, target as Decu"; 
String lastSelectSubQuery = builder.buildUnionSubQuery(
     null, 
     lastProjection, 
     columnsPresentInTable, 
     0, 
     getType(uri), 
     selection, 
     new String[]{ 
      String.valueOf(2015), 
      String.valueOf(12) 
     }, 
     null 
); 
String unionQuery = builder.buildUnionQuery(
     new String[]{ 
      firstSelectSubQuery, 
      [...] 
      lastSelectSubQuery 
     }, 
     sortOrder, 
     null 
); 
cursor = db.rawQuery(unionQuery, null); 

Этот подход может показаться вам немного сложнее, чем просто rawQuery и возможно, не ответ на ваш вопрос, но я использую его и рекомендую его в любом случае по двум причинам: потому что, когда есть способ сделать что-то, я всегда предпочитаю его использовать, и потому, что я считаю, что он позволяет мне поддерживать будущие модификации, для пример, если подход запроса выполняется с минимальными усилиями.