Add values in a row, substituing 0 for NULL - sqlite

I have a table that looks like this:
ID | VALUE A | VALUE B
----------------------
1 | 20 | NULL
2 | NULL | 100
3 | NULL | NULL
4 | 100 | 50
I want to run a query (Sqlite) that returns the ID and the sum of VALUE A and VALUE B (NULL should be zero). The result should look like:
ID | SCORE
----------
1 | 20
2 | 100
3 | 0
4 | 150

Try something like:
select ID, Ifnull(valuea, 0) + IfNull(valueb, 0) as Score From MyTable
reference:
http://www.sqlite.org/lang_corefunc.html#ifnull

Use IFNULL
select ID, IFNULL([VALUE A], 0) + IFNULL([VALUE B], 0) AS SCORE
from tbl1

Related

BigQuery - Duplicate rows x time using recursive method

I tried duplicating all rows in a table using the recursive method.
I have this base table
base
+------+
| rn |
+------+
| 1 |
| 2 |
| 3 |
+------+
Then, I want to replicate each of rows 3 times so the expected output would be like (9 rows)
+------+-------------+
| rn | iteration |
+------+-------------+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 1 | 2 |
| 2 | 2 |
| 3 | 2 |
| 1 | 3 |
| 2 | 3 |
| 3 | 3 |
+------+-------------+
I want to use recursive method
WITH recursive test AS (
SELECT
*,
1 AS iteration
FROM `base`
UNION ALL
SELECT
a.*,
b.iteration + 1 AS iteration
FROM `base` a
JOIN test b ON b.iteration < 3
)
SELECT *
FROM test
ORDER BY 2,1
But the result is not what I expected, it would produce 39 rows instead of 9 rows, it seems it's because of the JOIN that using cross join. Is there any way to fix the query to produce the expected value?
Thanks in advance!
Instead of RECURSIVE CTE, you can consider below
WITH base AS (
SELECT * FROM UNNEST([1, 2, 3]) rn
)
SELECT *
FROM base, UNNEST(GENERATE_ARRAY(1, 3)) iteration;
Query results
And for recursive approach, you need to add another join condition a.rn = b.rn.
WITH RECURSIVE base AS (
SELECT * FROM UNNEST([1, 2, 3]) rn
),
test AS (
SELECT *, 1 AS iteration FROM base
UNION ALL
SELECT b.*, a.iteration + 1
FROM test a
JOIN `base` b ON a.rn = b.rn AND a.iteration < 3
)
SELECT * FROM test ORDER BY 2,1;

Updating multiple rows in SQLite with relevant data from the same table

I have a database that I don't control the source of directly and results in errant '0' entries which mess up generated graphs with these drops to zero. I am able to manipulate the data after the fact and update that database.
It is acceptable that the last known good value can be used instead and so I am trying to make a general query that will remove all the zeros and populate it with the last known value.
Luckily, every entry includes the ID of the last entry and so it is a matter of simply looking back and grabbing it.
I have got very close to a final answer, but instead of updating with the last good value, it just uses the first value over and over again.
dummy data
CREATE TABLE tbl(id INT,r INT,oid INT);
INSERT INTO tbl VALUES(1,10,0);
INSERT INTO tbl VALUES(2,20,1);
INSERT INTO tbl VALUES(3,0,2);
INSERT INTO tbl VALUES(4,40,3);
INSERT INTO tbl VALUES(5,50,4);
INSERT INTO tbl VALUES(6,0,5);
INSERT INTO tbl VALUES(7,70,6);
INSERT INTO tbl VALUES(8,80,7);
SELECT * FROM tbl;
OUTPUT:
| id| r |oid|
|---|----|---|
| 1 | 10 | 0 |
| 2 | 20 | 1 |
| 3 | 0 | 2 | ** NEEDS FIXING
| 4 | 40 | 3 |
| 5 | 50 | 4 |
| 6 | 0 | 5 | ** NEEDS UPDATE
| 7 | 70 | 6 |
| 8 | 80 | 7 |
I have worked several queries to get results around what I am after:
All zero entries:
SELECT * FROM tbl WHERE r = 0;
OUTPUT:
| id | r | oid |
|----|----|-----|
| 3 | 0 | 2 |
| 6 | 0 | 5 |
Output only the those rows with the preceding good row
SELECT * FROM tbl WHERE A in (
SELECT id FROM tbl WHERE r = 0
UNION
SELECT oid FROM tbl WHERE r = 0
)
OUTPUT:
| id| r |oid|
|---|----|---|
| 2 | 20 | 1 |
| 3 | 0 | 2 |
| 5 | 50 | 4 |
| 6 | 0 | 5 |
Almost works
This is as close as I have got, it does change all the zero's, but it changes them all to the value of the first lookup
UPDATE tbl
SET r = (SELECT r
FROM tbl
WHERE id in (SELECT oid
FROM tbl
WHERE r = 0)
) WHERE r = 0 ;
OUTPUT:
| id| r |oid|
|---|----|---|
| 1 | 10 | 0 |
| 2 | 20 | 1 |
| 3 | 20 | 2 | ** GOOD
| 4 | 40 | 3 |
| 5 | 50 | 4 |
| 6 | 20 | 5 | ** BAD, should be 50
| 7 | 70 | 6 |
| 8 | 80 | 7 |
If it helps, I created this fiddle here that I've been playing with:
http://sqlfiddle.com/#!5/8afff/1
For this sample data all you have to do is use the correct correlated subquery that returns the value of r from the row with id equal to the current oid in the WHERE clause:
UPDATE tbl AS t
SET r = (SELECT tt.r FROM tbl tt WHERE tt.id = t.oid)
WHERE t.r = 0;
See the demo.

sqlite difference between rows

In SQLite I have a collection of records and I want to only show the records with specific differences.
The table has something like the following values:
file | idx | values
------|-------|----------------------
1 | 101 | 1,3,7,11,23,11
2 | 101 | 1,3,7,11,23,11
3 | 101 | 0,4,8,60,20,11
1 | 211 | 12,11,23
2 | 211 | 12,0,23
3 | 211 | 12,0,23
1 | 300 | 1
2 | 300 | 0
3 | 300 | 0
I want to be able to select two different fileIDs, and compare them.
I mean, I want to examine only records with (file = 1 AND file = 2)
What I cant to get back as a result is a collection of records that are not the same:
file | idx | values
------|-------|----------------------
1 | 211 | 12,11,23
2 | 211 | 12,0,23
1 | 300 | 1
2 | 300 | 0
So you do not want rows for which another row with the same idx and values values exists:
SELECT *
FROM MyTable
WHERE file IN (1, 2)
AND NOT EXISTS (SELECT *
FROM MyTable AS T2
WHERE file IN (1, 2)
AND file <> MyTable.file
AND idx = MyTable.idx
AND values = MyTable.values);
I just recieved an answer in another forum. This seems to work:
select * from thetable a, thetable b
where a.file <> b.file and a.idx = b.idx and a.values <> b.values and
a.file in (1, 2) and b.file in (1, 2);
Of course I change certain values as variables in a prepared statement. But it did the trick

distinct values as new columns & count

I'm trying to generate a summary from a table using SQLite as below.
I need to aggregate 1) number of times each model was driven, 2) total distance driven & 3) get distinct values for driver col & count the number of times each driver has driven the particular model - GROUP BY modelwith COUNT(model) & SUM(distance) will help with 1 & 2 - `I need help with the last part #3 , what is the right approach to find number of occurrences for each distinct values of a column and add them as new columns for each model ?
My table is:
id model datetime driver distance
---|-----|------------|--------|---------
1 | S | 04/03/2009 | john | 399
2 | X | 04/03/2009 | juliet | 244
3 | 3 | 04/03/2009 | borat | 555
4 | 3 | 03/03/2009 | john | 300
5 | X | 03/03/2009 | juliet | 200
6 | X | 03/03/2009 | borat | 500
7 | S | 24/12/2008 | borat | 600
8 | X | 01/01/2009 | borat | 700
Result would be
id model| drives distance john juliet borat
---|-----|--------|---------|------|------ |------
1 | S | 2 | 999 | 1 | 0 | 1
2 | X | 4 | 1644 | 0 | 2 | 2
3 | 3 | 2 | 855 | 1 | 0 | 1
OK... this time I got it!
select new_table.model, count (new_table.model) as drives, sum (new_table.distance) as distance,
sum(case when driver = 'john' then 1 else 0 end) as john,
sum(case when driver = 'juliet' then 1 else 0 end) as juliet,
sum(case when driver = 'borat' then 1 else 0 end) as borat
from new_table
group by model
It's not 100%, but this should get you most of the way there.
CREATE TABLE DBO.TEST_TABLE (ID INT,MODEL CHAR(1),DATETIME VARCHAR(255),DRIVER VARCHAR(255),DISTANCE INT)
INSERT INTO DBO.TEST_TABLE
VALUES
(1,'S','04/03/2009','JOHN',399)
,(2,'X','04/03/2009','JULIET',244)
,(3,'3','04/03/2009','BORAT',555)
,(4,'3','03/03/2009','JOHN',300)
,(5,'X','03/03/2009','JULIET',200)
,(6,'X','03/03/2009','BORAT',500)
,(7,'S','24/12/2008','BORAT',600)
,(8,'X','01/01/2009','BORAT',700)
Declare #Query_ nvarchar(MAX)
Declare #Cols_For_Pivot_ nvarchar(MAX)
SELECT #Cols_For_Pivot_= COALESCE(#Cols_For_Pivot_ + ',','') + QUOTENAME(DRIVER)
FROM (SELECT DISTINCT DRIVER FROM DBO.TEST_TABLE) AS PivotTable
IF OBJECT_ID('tempdb..#TEMP') IS NOT NULL DROP TABLE #TEMP
SET #Query_ =
N'SELECT DISTINCT
MODEL
,COUNT(DATETIME) OVER(PARTITION BY MODEL) AS DRIVES
,SUM(DISTANCE) OVER(PARTITION BY MODEL) AS DISTANCE
, ' + #Cols_For_Pivot_ + '
INTO #TEMP
FROM DBO.TEST_TABLE
PIVOT(COUNT(DRIVER)
FOR DRIVER IN (' + #Cols_For_Pivot_ + ')) AS P'
EXEC sp_executesql #Query_

update table in sorted order

I am maintaining table structure like below.
sortid | id | name
1 | 1 | aa
3 | 2 | cc
4 | 3 | cc
2 | 4 | bb
5 | 5 | dd
Where sortid is maintained according to ascending order of name.
Now I want to update name 'dd' to 'aa', such way that sort id is also updated to its correct value.
Update table set name="bb" where name like "dd";
After updating my table should become like below.
sortid | id | name
1 | 1 | aa
4 | 2 | cc
5 | 3 | cc
3 | 4 | bb
2 | 5 | aa
That sortid is the number of rows that would be sorted before this row.
So you can compute it by counting rows:
UPDATE MyTable
SET sortid = (SELECT COUNT(*)
FROM MyTable AS T2
WHERE T2.name < MyTable.name) +
(SELECT COUNT(*)
FROM MyTable AS T2
WHERE T2.name = MyTable.name
AND T2.id <= MyTable.id);
(The second subquery resolves duplicate sortid values that would result from duplicate names.)

Resources