BigQuery using firebase-analytics events getting error - android

I am new to BigQuery using firebase-analytics and trying to fetch data from the created event with custom param.
Getting error at line 13 on
UNNEST(user_dim.user_properties) user_properties
Error : Unrecognised name:user_dim; Did you mean by user_id?
I have tried with mentioned code.
SELECT
user_properties.value.value.string_value AS total_price,
AVG((
SELECT
SUM(value.string_value)
FROM
UNNEST(event_dim),
UNNEST(params)
WHERE
key = "quantity")) AS quantity
FROM
`uniorder-prod.analytics_200255431.events_*` t,
UNNEST(user_dim.user_properties) user_properties
WHERE
event_name = "total_consumption_res"
AND user_properties.key = "total_price"
I expect 2 columns one for total_price and another for the quantity which will some all quantity data.
Any ideas on how I can resolve this?

I was doing mistakes so If you want the result you can refer to this answer.
//Query to run on BigQuery Console, you can change event param as per your
//need
SELECT
param2.value.string_value AS item_name,
SUM(param3.value.double_value) AS quantity,
SUM(param4.value.double_value) AS total_price
FROM
`uniorder-prod.analytics_200255431.events_*`,
UNNEST(event_params) AS param1,
UNNEST(event_params) AS param2,
UNNEST(event_params) AS param3,
UNNEST(event_params) AS param4
WHERE
event_name = "total_consumption_res"
AND param1.key = "user_id"
AND param1.value.int_value = 118
AND param2.key = "item_name"
AND param3.key = "quantity"
AND param4.key = "total_price"
GROUP BY
item_name
ORDER BY
total_price DESC

Your query seems to be created for the old database schema, it has been flattened a bit since then so you no longer need to unnest user_dim (or event_dim) to access user_properties.
Check out the new schema here: https://support.google.com/firebase/answer/7029846?hl=en

Related

How do I perform a Room DAO multi table join #Query using select fields?

My Problem:
I'm struggling to eliminate the compiling error on the following Room #Query statement in a Room DAO. As you can see, the SQLite query statement is joining various fields from different tables. The missing fields identified by the error are a part of the Notes class constructor identified in the List type for the method. I think I need to change the List type identified. If I'm right, I need some guidance/suggestion on how I should resolve it. Do I need to create a new Class and DAO with just those specific fields queried? Or maybe just a class since there is not table specific to these fields only. The error is:
error: The columns returned by the query does not have the fields [commentID,questionID,quoteID,termID,topicID,deleted] in com.mistywillow.researchdb.database.entities.Notes even though they are annotated as non-null or primitive. Columns returned by the query: [NoteID,SourceID,SourceType,Title,Summary]
List getNotesOnTopic(String topic);
#Query("SELECT n.NoteID, s.SourceID, s.SourceType, s.Title, c.Summary FROM Comments as c " +
"LEFT JOIN Notes as n ON n.CommentID = c.CommentID " +
"LEFT JOIN Sources as s ON n.SourceID = s.SourceID " +
"LEFT JOIN Topics as t ON n.TopicID = t.TopicID WHERE t.Topic = :topic AND n.Deleted = 0")
List<Notes> getNotesOnTopic(String topic);
What I'm trying to do:
I'm attempting to convert and existing Java desktop app with an embedded an SQLite database. The above query does work fine in that app. I only want to pass field data from these tables.
What I've tried:
I've done some googling and visited some forums for the last few days (e.g. Android Forum, Developer.Android.com) but most of the Room #Query examples are single table full field queries (e.g. "Select * From table"). Nothing I found yet (there is probably something) quite addresses how and what to do if you are joining and querying only specific fields across tables.
I think I may have fixed my issue. I just created a new class called SourceTable and designated the queried fields in the constructor. The only catch was I, according to a follow up error, was that the parameters had to match the field names.
public class SourcesTable {
private int NoteID;
private int SourceID;
private String SourceType;
private String Title;
private String Summary;
public SourcesTable(int NoteID, int SourceID, String SourceType, String Title, String Summary){
this.NoteID = NoteID;
this.SourceID = SourceID;
this.SourceType = SourceType;
this.Title = Title;
this.Summary = Summary;
}
}
and then I update my list method:
List<SourcesTable> getNotesOnTopic(String topic);

android sqlite query "!=" multiple whereargs [duplicate]

I have a rather big query that is returning data when executed outside android while returning nothing when executed within android.
I split the query in several pieces and determined that the union was ok.
I tried on a smaller set of data with the same behavior.
I've tested with different hardware and API versions.
I'm using the rawQuery method with constant values.
http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#rawQuery(java.lang.String, java.lang.String[])
This query was meant to replace a FULL OUTER JOIN which is not currently supported.
SELECT IFNULL(stype, gtype) AS type, IFNULL(sdate, gdate) AS date, IFNULL(sroute, groute) AS route FROM (
SELECT sp.type AS stype, sp.date AS sdate, -1 AS gtype, gp.date AS gdate, sp.route AS sroute, gp.route AS groute
FROM Sensor_Point AS sp LEFT JOIN GPS_Point AS gp ON gp._id IS NULL AND sp.sent=0 AND sp.route=gp.route AND sp.route=1
UNION ALL
SELECT sp.type AS stype, sp.date AS sdate, -1 AS gtype, gp.date AS gdate, sp.route AS sroute, gp.route AS groute
FROM GPS_Point AS gp LEFT JOIN Sensor_Point AS sp ON sp._id IS NULL AND gp.sent=0 AND sp.route=gp.route AND gp.route=1
) WHERE route=1 ORDER BY date ASC LIMIT 255
Any hints would be greatly appreciated.
Update:
Look's like the problem is finally with the query parameters, if I set it this way:
String[] args = new String[3];
args[0] = args[1] = args[2] = "1";
Cursor data dataBase.rawQuery(SELECT_POINTS, args);
It doesn't work, while it works when hardcoding values directly in the query.
Cursor data = dataBase.rawQuery(SELECT_POINTS, null);
In the Android database API, all query parameters are strings.
(This is a horrible design mistake.)
Your query corresponds to:
... AND sp.route='1'
Try to convert the parameter strings back into a number like this:
... AND sp.route = CAST(? AS INT)
or just put the number directly into the query string.

Ormlite orderBy max(ColumnName)

Hi I need to use order by max(columnName) in ORMLite. I have the SQL query but I need to know how this query is used. This is my query:
SELECT * FROM table where place = 'somePlace' group by name
order by MAX (statusDate)
statusDate column contains date in "yyyy-dd-mm" format. The result I got is the list with recentDates.
Use a query builder, and function where and orderBy to preoceed
QueryBuilder<YourObject, Integer> q = yourDaoObject.queryBuilder();
Where<YourObject, Integer> wh = q.where();
wh.eq("place", "some_place");
q.orderBy("statusDate", false);
List<YourListOfObects> yourList = q.query();
But before that you should store a long instead to store your Date https://stackoverflow.com/a/6993420/2122876
i got same names with different dates and i need only the recent date.
If you are trying to get element from Table with the maximum statusDate then you should be doing an descending order-by with a limit of 1. Something like:
QueryBuilder<Foo, Integer> qb = fooDao.queryBuilder();
qb.where().eq("place", "some_place");
qb.orderBy("sttusDate", false); // descending sort
// get the top one result
qb.limit(1);
Foo result = qb.queryForFirst();
I did something like this. Please create your own query builder on the first line.
QueryBuilder<MyRowObject, Integer> queryBuiler = "Get Query builder" //getDaoXXX().queryBuilder();
MyRowObject firstLatestRow = queryBuiler.orderBy("dateColoumn", false).queryForFirst();
Hope this helps

How do I create a group with a source_id reference?

Update
I finally figured this one out:
The key is to create the group with an account name and account type, something that is not really apparent looking at the documentation (there are no fields with those name in ContactsContract.Groups they are in the SyncColumns). When you create the group with those two values, the sync process will generate the source_id for you, at which point you can add member using either the group row id or the source_id.
Here is some sample code if anyone needs it.
ContentValues values = new ContentValues();
values.put(ContactsContract.Groups.TITLE,"yourGroupName");
values.put(ContactsContract.Groups.ACCOUNT_TYPE,"com.google");
values.put(ContactsContract.Groups.ACCOUNT_NAME,"someuser#gmail.com");
values.put(ContactsContract.Groups.GROUP_VISIBLE,1);
context.getContentResolver().insert(ContactsContract.Groups.CONTENT_URI, values);
then to add members:
values = new ContentValues();
values.put(ContactsContract.CommonDataKinds.GroupMembership.MIMETYPE,ContactsContract.CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE);
values.put(ContactsContract.CommonDataKinds.GroupMembership.RAW_CONTACT_ID, 22);
//values.put(ContactsContract.CommonDataKinds.GroupMembership.GROUP_ROW_ID, 56);
// the above or
values.put(ContactsContract.CommonDataKinds.GroupMembership.GROUP_SOURCE_ID,"sourceIdthatIsFilledInAfterSync");
//context.getContentResolver().insert(ContactsContract.Data.CONTENT_URI,values);
Original question:
I have been struggling with an issue related to syncing group memberships and think I figured out the cause, but I don't know how to fix it.
After creating 2 groups , one via code the the other manually and then query the groups using these columns.
private final static String[] GROUP_COLUMNS = {
ContactsContract.Groups._ID,
ContactsContract.Groups.DATA_SET,
ContactsContract.Groups.NOTES,
ContactsContract.Groups.SYSTEM_ID,
ContactsContract.Groups.GROUP_VISIBLE,
ContactsContract.Groups.DELETED,
ContactsContract.Groups.SHOULD_SYNC,
ContactsContract.Groups.SOURCE_ID,
ContactsContract.Groups.TITLE
};
I can dump out the results as this.
: --- begin ---
: key = title , value = myNewTestGroup
: key = data_set , value = null
: key = _id , value = 45
: key = sourceid , value = null
: key = group_visible , value = 1
: key = system_id , value = null
: key = should_sync , value = 1
: key = notes , value = myNewTestGroup
: key = deleted , value = 0
: --- end ---
: --- begin ---
: key = title , value = Mytest2
: key = data_set , value = null
: key = _id , value = 46
: key = sourceid , value = 144c8b8d0cca8a52
: key = group_visible , value = 1
: key = system_id , value = null
: key = should_sync , value = 1
: key = notes , value = Mytest2
: key = deleted , value = 0
: --- end ---
The manually create group (Mytest2) has a souceid which is listed as a column in ContactsContract.SyncColumns, while the code generated group has null.
I see references to source_id in may places in the android docs but I can't see how to obtain one.
I think somehow i would get this if i associate the group with an account.
Does anyone know how to associate at group with an account, or otherwise get this source id field set?
I finally figured this one out: The key is to create the group with an account name and account type, something that is not really apparent looking at the documentation (there are no fields with those name in ContactsContract.Groups they are in the SyncColumns). When you create the group with those two values, the sync process will generate the source_id for you, at which point you can add member using either the group row id or the source_id.
Here is some sample code if anyone needs it.
ContentValues values = new ContentValues();
values.put(ContactsContract.Groups.TITLE,"yourGroupName");
values.put(ContactsContract.Groups.ACCOUNT_TYPE,"com.google");
values.put(ContactsContract.Groups.ACCOUNT_NAME,"someuser#gmail.com");
values.put(ContactsContract.Groups.GROUP_VISIBLE,1);
context.getContentResolver().insert(ContactsContract.Groups.CONTENT_URI, values);
then to add members:
values = new ContentValues();
values.put(ContactsContract.CommonDataKinds.GroupMembership.MIMETYPE,ContactsContract.CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE);
values.put(ContactsContract.CommonDataKinds.GroupMembership.RAW_CONTACT_ID, 22);
//values.put(ContactsContract.CommonDataKinds.GroupMembership.GROUP_ROW_ID, 56);
// the above or
values.put(ContactsContract.CommonDataKinds.GroupMembership.GROUP_SOURCE_ID,"sourceIdthatIsFilledInAfterSync");
context.getContentResolver().insert(ContactsContract.Data.CONTENT_URI,values);
The data in sourceid still needs to be set in the second example before you are able to retrieve it.
here is what the docs have to say about sourceid:
String SOURCE_ID read/write:
String that uniquely identifies this row to its source account.
Typically it is set at the time the raw contact is inserted and never
changed afterwards. The one notable exception is a new raw contact: it
will have an account name and type (and possibly a data set), but no
source id. This indicates to the sync adapter that a new contact needs
to be created server-side and its ID stored in the corresponding
SOURCE_ID field on the phone.

Android development with sqlite: query result shouldn't be empty

I have a rather big query that is returning data when executed outside android while returning nothing when executed within android.
I split the query in several pieces and determined that the union was ok.
I tried on a smaller set of data with the same behavior.
I've tested with different hardware and API versions.
I'm using the rawQuery method with constant values.
http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#rawQuery(java.lang.String, java.lang.String[])
This query was meant to replace a FULL OUTER JOIN which is not currently supported.
SELECT IFNULL(stype, gtype) AS type, IFNULL(sdate, gdate) AS date, IFNULL(sroute, groute) AS route FROM (
SELECT sp.type AS stype, sp.date AS sdate, -1 AS gtype, gp.date AS gdate, sp.route AS sroute, gp.route AS groute
FROM Sensor_Point AS sp LEFT JOIN GPS_Point AS gp ON gp._id IS NULL AND sp.sent=0 AND sp.route=gp.route AND sp.route=1
UNION ALL
SELECT sp.type AS stype, sp.date AS sdate, -1 AS gtype, gp.date AS gdate, sp.route AS sroute, gp.route AS groute
FROM GPS_Point AS gp LEFT JOIN Sensor_Point AS sp ON sp._id IS NULL AND gp.sent=0 AND sp.route=gp.route AND gp.route=1
) WHERE route=1 ORDER BY date ASC LIMIT 255
Any hints would be greatly appreciated.
Update:
Look's like the problem is finally with the query parameters, if I set it this way:
String[] args = new String[3];
args[0] = args[1] = args[2] = "1";
Cursor data dataBase.rawQuery(SELECT_POINTS, args);
It doesn't work, while it works when hardcoding values directly in the query.
Cursor data = dataBase.rawQuery(SELECT_POINTS, null);
In the Android database API, all query parameters are strings.
(This is a horrible design mistake.)
Your query corresponds to:
... AND sp.route='1'
Try to convert the parameter strings back into a number like this:
... AND sp.route = CAST(? AS INT)
or just put the number directly into the query string.

Categories

Resources