How to combine 2 columns into a new one in sqlite - android

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.

Related

Update SQLite column with text of maximum length from same row

I have an (Android) SQLite table with two columns, Col1 and Col2, containing text. I want to update Col1 to contain the text with the maximum length out of Col1 and Col2 from the same row. I already have a working query but that query takes pretty long to execute on a large data set.
Example data:
| Col1 | Col2 | ...
---------------
| AB | A |
| A | ABC |
| AB | ABCD |
Expected update result:
| Col1 | ...
--------
| AB |
| ABC |
| ABCD |
Working (but slow and hard to read) query:
UPDATE table
SET Col1 = (
SELECT Col2
FROM table AS innerTable
WHERE table.ROWID = innerTable.ROWID)
WHERE length(Col1) < length(Col2)
I am basically looking for something like this, without nested queries:
UPDATE table SET Col1 = maxLengthString(Col1, Col2)
Is there any existing function I have overlooked? Note that this is SQLite, so I can not use CREATE FUNCTION.
Thank you for your help!
I think that it is as simple as that:
update tablename
set col1 = col2
where length(col2) > length(col1);
Only the rows where the length of col1 is less than the length of col2 will be updated.
See the demo.
Results:
| Col1 | Col2 |
| ---- | ---- |
| AB | A |
| ABC | ABC |
| ABCD | ABCD |

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 select values sum same ID

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

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.

Categories

Resources