SQLITE select values sum same ID - android

I have a table called transactions with the following schema:
ID | P_Name | O_ID | P_ID | P_Qty |
===============================================
1 | PRODUCT A | 1 | 140 | 100 |
2 | PRODUCT A | 1 | 140 | 15 |
3 | PRODUCT B | 1 | 130 | 10 |
4 | PRODUCT C | 1 | 120 | 2 |
I want to sum all P_Qty that share a P_Name so I can eventually end up with:
P_Name | P_ID | P_Qty |
===============================
PRODUCT A | 140 | 115 |
PRODUCT B | 130 | 10 |
PRODUCT C | 120 | 2 |
As you can see the P_Qty is summed where the P_ID is same, I am using a ContentResolver as shown below its however failing as shown:
String selection = null;
String[] selectionArgs = null;
String orderBy = TRANSACTION_PRODUCT_NAME + " ASC";
Cursor cursor = getActivity().getContentResolver().query(
SalesManContract.TRANSACTION_CONTENT_URI,
new String[] {TRANSACTION_PRODUCT_NAME," SUM(P_Qty) AS
P_Qty"},
selection,
selectionArgs,
orderBy);
The result is:
P_Name | P_ID | P_Qty |
===============================
PRODUCT A | 140 | 127 |
How can I achieve my desired result using ContentResolver

Related

Sqlite - How to i query like call log if there is same number continue get as single record with continuously record count only?

UniqueID | MobileNumber | createDate
-----------+---------+-----+------------+-----------
U_23121 | 987654 | 2013-02-05
U_23124 | 987654 | 2013-02-02
U_23122 | 845263 | 2013-01-18
U_23128 | 654789 | 2013-01-16
U_23123 | 735689 | 2013-01-12
U_23128 | 654789 | 2013-01-11
U_23128 | 654789 | 2013-01-10
U_23126 | 987654 | 2013-01-09
U_23125 | 845263 | 2013-01-07
U_23126 | 845263 | 2013-01-06
U_23125 | 987654 | 2013-01-05
I want to record like filtering with mobile number if more then one continue get latest based on createdDate and get count for that like
UniqueID | Mobile_Number | createDate | count
-----------+---------+-----+------------+-----------
U_23121 | 987654 | 2013-02-05 | 2
U_23122 | 845263 | 2013-01-18 | 1
U_23128 | 654789 | 2013-01-16 | 1
U_23123 | 735689 | 2013-01-12 | 1
U_23128 | 654789 | 2013-01-11 | 2
U_23126 | 987654 | 2013-01-09 | 1
U_23125 | 845263 | 2013-01-07 | 2
U_23125 | 987654 | 2013-01-05 | 1
I'll get record that is need from following query but not getting count
SELECT te.*
FROM tableName as te
WHERE te.Mobile_Number <> (select Mobile_Number
from tableName
where createDate > te.createDate
limit 1
)
ORDER BY te.createDate DESC
This is a gaps-and-islands problem. One solution is to assign a "grp" to each row and then aggregate by that group.
You can assign the grp by counting the number of mobile numbers that are different from the mobile number in each row, up to that row. This is a constant value for adjacent mobile numbers.
The resulting query:
SELECT MAX(UniqueId), MobileNumber,
MAX(createDate), COUNT(*)
FROM (SELECT te.*,
(SELECT COUNT(*)
FROM tableName te2
WHERE te2.createDate < te.createDate AND
te2.MobileNumber <> te.MobileNumber
) as grp
FROM tableName te
) te
GROUP BY MobileNumber, grp;
ORDER BY MIN(tcreateDate) DESC
Ok, this is the gaps and islands problem. If your Sqllite supports the row_number function (version 3.25 and more) then you can use the following approach
select MobileNumber, max(createDate), count(*)
from
(
select *,
row_number() over (order by createDate) -
row_number() over (partition by MobileNumber order by createDate) grp
from data
) t
group by grp, MobileNumber
USE GROUP BY
SELECT te.* FROM tableName as te where te.Mobile_Number != (select Mobile_Number from tableName where createDate > te.createDate limit 1) GROUP BY Mobile_Number ORDER BY te.createDate DESC

SQLite many to many join and group

This is a very normal setup for many-to-many relational tables.
product list and category list.
Each product belongs to (0,n) category.
Each category contains (0,n) product.
TABLES
CREATE TABLE product (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL);
CREATE TABLE category (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL);
CREATE TABLE product_category (
product_id INTEGER NOT NULL,
category_id INTEGER NOT NULL);
PRODUCT table
| id | name |
=============
| 1 | p1 |
| 2 | p2 |
| 3 | p3 |
CATEGORY table
| id | name |
=============
| 1 | c1 |
| 2 | c2 |
| 3 | c3 |
PRODUCT_CATEGORY table
| product_id | category_id |
============================
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 2 | 1 |
| 2 | 2 |
| 3 | 1 |
Question
I would like to know how to query for product by category_id and have the product listed with all category_id that it is in.
For example, I want to query the list of products that are available in category = 1, and the result must contain a categories_id where all categories that the product belongs to must be listed.
Expected output
| product_id | product_name | categories_id |
=============================================
| 1 | p1 | 1,2,3 |
| 2 | p2 | 1,2 |
| 3 | p3 | 1 |
Attempts
I know this can be done with sub query, but I would like to know whether this can be achieved by JOIN statement?
I have tried the following query but the results does not reflect what I want.
JOIN QUERY statement
SELECT
P.id AS product_id,
P.name AS product_name,
GROUP_CONCAT(PC.category_id, ',') AS categories_id
FROM product AS P
LEFT JOIN product_category AS PC
ON P.id = PC.product_id
WHERE PC.category_id = 1
GROUP BY P.id;
Output (not as intended)
| product_id | product_name | categories_id |
=============================================
| 1 | p1 | 1 |
| 2 | p2 | 1 |
| 3 | p3 | 1 |
Can anyone advice on how this can be achieved?
Here is SqlFiddle for the execution and query is
SELECT P.id AS product_id, P.name AS product_name,
GROUP_CONCAT(PC2.category_id) AS categories_id
FROM
product AS P LEFT JOIN product_category AS PC ON
P.id = PC.product_id LEFT JOIN product_category AS PC2 ON
P.id = PC2.product_id
WHERE PC.category_id = 1
GROUP BY P.id;
SELECT
p.id,
p.name,
GROUP_CONCAT(pc2.category_id, ',')
FROM product_category pc1
JOIN product_category pc2
JOIN product p
WHERE pc1.category_id = 1
AND pc1.product_id = pc2.product_id
AND p.id = pc1.product_id
GROUP BY pc1.product_id;

Android - SQLite Select the first N occurrences of each differing column value

Suppose I have a SQL table "songs" with three columns: "title", "artist" and "ranking":
track | artist | ranking
---------+--------+---------
A | A1 | 3
B | A1 | 2
C | A1 | 1
D | A2 | 4
E | A3 | 7
F | A3 | 6
G | A3 | 5
I want to make a SELECT query that will return just the first N (e.g. two) row for each artist while ordering by the ranking. I'm aware that using GroupBy on the artist column will return one row of each artist, however I want two in this scenario like so:
track | artist | ranking
---------+--------+---------
A | A1 | 1
B | A1 | 2
D | A2 | 4
E | A3 | 5
F | A3 | 6
If it is possible, I would preferably want to construct this within android using a queryBuilder, this is as close as I managed to get:
SQLiteDatabase db = getReadableDatabase();
SQLiteQueryBuilder qBuilder = new SQLiteQueryBuilder();
String[] sqlSelect = {"title", "artist", "ranking"};
String sqlTable = "songs";
String orderBy = "ranking DESC";
qBuilder.setTables(sqlTable);
cur = qBuilder.query(db, sqlSelect, null, null, null, null, orderBy);
I have seen related questions, however I haven't been able to find a way to apply it to this scenario - any direction on how to accomplish this would be appreciated.

How to combine 2 columns into a new one in sqlite

I have a table with 3 columns and I have to put the values from 2 columns into one in descending order.
+---+---+---+
| A | B | C |
+---+---+---+
| z | 1 | 2 |
| f | 5 | 7 |
| s | 9 | 5 |
+---+---+---+
Using this example the output would be putting the values from column B and C into one like this:
+---+----+
| A | B |
+---+----+
| s | 9 |
| f | 7 |
| f | 5 |
| s | 5 |
| z | 2 |
| z | 1 |
+---+----+
My current code:
String SELECT_QUERY = "SELECT a, b, c AS b FROM _table ORDER BY b DESC" ;
How can I do this?
Thanks.
First combine the two queries using UNION and then do the descending order to the combined result.
Query
SELECT * FROM
(
SELECT A,B
FROM tbl
UNION
SELECT A,C
FROM tbl
)t
ORDER BY t.B DESC;
In your case,
String SELECT_QUERY = "SELECT * FROM (SELECT A,B FROM _table UNION SELECT A,C FROM _table)t ORDER BY t.B DESC" ;
Fiddle demo for your reference
Screenshot
Hope this will help you out.

Update row in SQLite without all information from the dataset

I create some Objects based on information from my database. My table looks like this:
tbl_Book
+-----+-------+---------+-------+------+
| _id | Title | Author | Pages | ISBN |
+-----+-------+---------+-------+------+
| 1 | Test1 | Author1 | 111 | 1234 |
| 2 | Test2 | Author2 | 222 | 2345 |
| 3 | Test3 | Author | 333 | 3456 |
+-----+-------+---------+-------+------+
My created Objects only need the information from id, title and the ISBN so I only select these values from the database to create my Object. Now I want to update only the ISBN in the database so I have a method in my Object with this code:
Book b = new Book(id, title, isbn);
b.setISBN(value);
// Code from setISBN
public void setISBN(int isbn)
{
this.isbn= isbn;
// DB updaten
ContentValues cv = new ContentValues();
cv.put("_id", getId());
cv.put("ISBN", isbn);
db.replace("tbl_Book", null, cv);
}
But with this method it comes to a SQLiteConstraintException because author, title and page are null. How can I update a row in an table if I only have some information from the dataset? All other items from the dataset should not be touched.
Why not using Update()? It seems that the _id is your table's primary key. If your intention is just to update a record when you already have the primary key then it should be pretty simple:
String whereClause = "_id=" + getId();
ContentValues cv = new ContentValues();
cv.put("ISBN", isbn);
//update(String table,ContentValue value, String whereClause, String[] whereArgs)
db.update("tbl_Book", cv, whereClause, null);
As far as I know (maybe I'm wrong), Replace() will first delete a row if it exists and then inserts a new record based on provided values. In your case I think, it deletes the corresponding record (based on the id) and then try to insert new one:
For instance let's say the _id is 1:
+-----+-------+---------+-------+------+
| _id | Title | Author | Pages | ISBN |
+-----+-------+---------+-------+------+
| 1 | Test1 | Author1 | 111 | 1234 |
will be replaced by:
+-----+-------+---------+-------+------+
| _id | Title | Author | Pages | ISBN |
+-----+-------+---------+-------+------+
| 1 | NULL | NULL | NULL | 4321 |
Which I don't think that fits your need. Therefore, I think for your purpose the Update suits better.

Categories

Resources