Odd sqlite3 behavior for WHERE clause on TEXT column - sqlite

So, I've got a table.
sqlite> .schema
CREATE TABLE data(date int primary key, temp text, humi text, co2 text, coarse int);
It's got some data, and using a WHERE condition on a TEXT column does what I'd expect:
sqlite> SELECT * FROM data WHERE temp > 26;
date temp humi co2 coarse
---------- ---------- ---------- ---------- ----------
1569962962 26.01 30.97 530.34 1
1569963029 26.05 30.91 528.57 0
1569963097 26.05 30.87 530.16 0
1569963164 26.09 30.83 530.37 1
1569963232 26.09 30.84 530.75 0
1569963300 26.13 30.77 532.51 0
It also does what I expect when I give it a condition none of the rows match:
sqlite> select * from data where temp > 99;
sqlite>
Unless I use 100, or 1000, etc. Then it ignores the WHERE and gives me every row:
sqlite> select * from data where temp > 100;
date temp humi co2 coarse
---------- ---------- ---------- ---------- ----------
1569967795 25.99 31.65 558.03 1
1569967863 26.01 31.60 558.78 0
1569967930 26.02 31.64 557.77 0
1569967998 26.01 31.65 556.68 1
1569968067 26.02 31.63 557.31 0
1569968134 26.04 31.64 560.01 0
1569968201 26.08 31.66 559.84 1
1569968268 26.05 31.66 563.95 0
1569968335 26.08 31.70 562.86 0
1569968403 26.09 31.69 563.85 1
1569968471 26.09 31.73 565.58 0
1569968539 26.11 31.69 566.04 0
1569968607 26.13 31.69 564.95 1
1569968674 26.13 31.62 565.51 0
1569968742 26.16 31.63 567.40 0
1569968810 26.16 31.60 568.38 1
[snip]
I, of course, discovered this by doing a DELETE operation with a WHERE clause to remove some bad data. It's okay, I've mostly stopped crying now. (The historical sensor data was not important) But why the behavior on multiples of 10? I assume it's doing something too-clever with flexible typing, but I don't see where.

It's because you are doing a textual comparison (due to temp having a TEXT column affinity) so 1 is lower than 200 (i.e. the character 1 is lower than the value 2 so the other characters are insignificant).
You need to force a numerical comparison and this can be done by CASTing e.g.
SELECT * FROM data WHERE CAST(temp AS REAL) > 99;
or
SELECT * FROM data WHERE temp > CAST(99 AS REAL);
You may wish to have a look at CAST expressions
If the column type of the temp column were REAL as per
CREATE TABLE data(date int primary key, temp REAL /*<<<<<<<<<< CHANGED */, humi text, co2 text, coarse int);`
then the CAST would not be required.

Related

REGEXP_SIMILAR in Teradata

I am trying to take out names from a table where name does not contain characters or numbers.
Name Flag
Abc 0
124 0
£% 1
AB÷ 0
17 0
*& 1
What function to be used in Teradata to achieve the desired result?
Best,

SQLite3 IF statement, condition based on other columns

Here's my table:
sqlite> SELECT * from portafolio WHERE my_id=1;
id my_id stock name shares price date
---------- ---------- ---------- ------------- ---------- ---------- -------------------
1 1 NFLX Netflix, Inc. 2 133.26 2017/01/19 06:40AM
2 1 GM General Motor 1 37.47 2017/01/19 06:40AM
3 1 NFLX Netflix, Inc. -2 133.26 2017/01/19 06:41AM
4 1 NFLX Netflix, Inc. 4 133.26 2017/01/19 06:41AM
I'd like to make the price negative if shares is negative.
I know that I have to use CASE but don't know how to properly implement it, here's my attempt:
sqlite> SELECT CASE
...> WHEN shares<0
...> THEN price=price*-1
...> END, stock,shares,price FROM portafolio;
Output:
CASE
WHEN shares<0
THEN price=price*-1
END stock shares price
------------------------------------------ ---------- ---------- ----------
NFLX 2 133.26
GM 1 37.47
0 NFLX -2 133.26
NFLX 4 133.26
ST 1 41.2
HA 5 56.65
0 ST -1 41.2
0 HA -3 56.65
0 HA -2 56.65
GM 1 37.47
0 GM -1 37.47
Any help would be appreciated guys.
You don't have any ELSE case in your query. Without ELSE there will be no results if shares is less than zero. Also, you don't need to assign price * -1 to price. Just use it like this:
CASE WHEN shares < 0
THEN price * -1
ELSE price
END

SQLite : Need to combine results from one table with another result

I have 2 tables :
payments:
id amount type code
1 1200 0 111
2 100 1 111
3 200 0 111
4 50 0 112
5 500 2 112
6 300 3 113
bills:
id details code
-----------------------
1 bill-1 111
2 bill-2 112
3 bill-3 113
4 bill-4 114
I wanted to sum the amounts in payments table and join it with bills like below
result:
bills.code type0Sum type1Sum type2Sum type3Sum
-------------------------------------------------------------------------
111 1400 100 0 0
112 50 0 500 0
113 0 0 0 300
114 0 0 0 0
Sorry if this is a newbie question
[Edit]
I have used a similar query as below :
SELECT *
FROM bills,
(SELECT SUM(amount) AS type0Sum, code
FROM payments
WHERE type = 0
GROUP BY code)
AS sub1,
(SELECT SUM(amount) AS type1Sum, code
FROM payments
WHERE type = 1
GROUP BY ref_code)
AS sub2
WHERE bills.code = sub1.code
AND bills.code = sub2.code
But I am getting only the rows those having the type like :
bills.code type0Sum type1Sum type2Sum type3Sum
-------------------------------------------------------
111 1400 100
I've modified that final query to do proper joins, not the old joins that you were doing (read up on cartesian joins). Give this one a go for you, see if it works;
SELECT b.code
,sub1.type0Sum
,sub2.type1Sum
FROM bills b
LEFT JOIN (
SELECT SUM(amount) AS type0Sum
,code
FROM payments
WHERE type = 0
GROUP BY code
) AS sub1 ON b.code = sub1.code
LEFT JOIN (
SELECT SUM(amount) AS type1Sum
,code
FROM payments
WHERE type = 1
GROUP BY ref_code
) AS sub2 ON b.code = sub2.code
There are other ways of doing this that are more efficient but I've kept to your query in order to help you learn.

R Programming - Update mysql db rows where a condition is met

I have a data frame that is structured identical to a table in my mysql db. I want to update the rows of the mysql db where the primary key of my data frame and that table match.
For example
DF 1
PK Count Temperature
3 1 111
4 2 100
5 3 190
6 4 200
MySQL Table
PK Count Temperature
1 1 100
2 10 11
3 0 0
4 0 0
5 0 0
6 0 0
7 0 0
8 0 0
Notice that I can't simply overwrite the table because I have rows in my DB that do not exist in my data frame.
After the update, what I would like to have is the following table.
PK Count Temperature
1 1 100
2 10 11
3 1 111
4 2 100
5 3 190
6 4 200
7 0 0
8 0 0
Thoughts?
So, I haven't been able to directly update a row. However, what I have done is create a holding table in my DB that I can append to from R. I then created a trigger in my db to update the desired rows in my desired table. From their, I have created another trigger to empty my holding table.
This is sort of what Dean was suggesting, but a little different.
Here, I am providing alternative approach over writing frame to a temp table and performing update in the main table or getting holding table, append, and update desired table by trigger method.
I believe following approach is easy and effective as it performs update record directly in the target table.
#install.packages("RMySQL")
#install.packages("DBI")
library(DBI)
library(RMySQL)
#Establish the connection
mydb = dbConnect(MySQL(),
user='your user',
password='your password',
dbname='your DB name',
host='Host Name')
#Eusuring the connection working by listing table
dbListTables(mydb)
#Applying update statement directly
rs = dbSendQuery(mydb, "UPDATE DB_NAME.TABLE_1
SET FIELD_1 = 0
WHERE ID = 5")
#Verifying the result
rs = dbSendQuery(mydb, "SELECT * FROM DB_NAME.TABLE_1
WHERE ID = 5")
data = fetch(rs, n=-1)
print(data)
I have tried above code in R Studio Version 1.1.453 and R 3.5.0 (64bit).

sql query help for the table below

my table structure is :
table_system:
"ID" NUMBER NOT NULL ENABLE,
"COUNTRY" VARCHAR2(10 BYTE) NOT NULL ENABLE,
"COMPANYCODE" VARCHAR2(50 BYTE) NOT NULL ENABLE,
"SYSTEM" VARCHAR2(50 BYTE) NOT NULL ENABLE,
"NOTSTARTED" NUMBER,
"RUNNING" NUMBER,
"COMPLETED" NUMBER,
"ACTUALSTARTTIME" VARCHAR2(5 BYTE),
"ACTUALENDTIME" VARCHAR2(5 BYTE),
"SEQUENCE" NUMBER,
"PLANNEDSTARTTIME" VARCHAR2(5 BYTE),
"PLANNEDENDTIME" VARCHAR2(5 BYTE),
"ESTIMATEDENDTIME" VARCHAR2(5 BYTE),
CONSTRAINT "SYSTEMRUNTIME_PK" PRIMARY KEY ("ID", "COUNTRY", "COMPANYCODE", "SYSTEM") USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) TABLESPACE "SYSTEM" ENABLE
I need an output that will fetch me the following output:
COMPANYCODE SYSTEM1 SYSTEM2 SYSTEM3 SYSTEM4 SYSTEM5 SYSTEM6 SYSTEM7 SYSTEM8 … SYSTEM N
-------------------------------------------------- --------------------------- ------------------- ----------------------- ------------------------------ ------------------------------ -------------------- -------------- -------------- -------------- --------------
where systems are sorted as per the "SEQUENCE" attribute.
I have tried this query :
select distinct companycode, sequence, system,notstarted,running,completed
from table_system
where id = (select max(id) from table_system)
order by companycode, sequence
this fetches me the following
COMPANYCODE SEQUENCE SYSTEM NOTSTARTED RUNNING COMPLETED
-------------------------------------------------- ---------------------- -------------------------------------------------- ---------------------- ---------------------- ----------------------
1001 Helsinki Branch 1 GAP 2 / Datastage GL 0 0 3
1001 Helsinki Branch 2 SAP GL 0 0 2
1001 Helsinki Branch 3 SAP BW 0 0 2
1002 Copenhagen Branch 1 GAP 2 / Datastage GL 0 0 3
1002 Copenhagen Branch 2 SAP GL 0 0 2
1002 Copenhagen Branch 3 SAP BW 0 0 2
1003 Oslo Branch 1 GAP 2 / Datastage GL 0 0 3
1003 Oslo Branch 2 SAP GL 0 0 2
1003 Oslo Branch 3 SAP BW 0 0 2
1004 (publ) (EUR) 1 EKO 0 0 13
1004 (publ) (EUR) 2 HA Core 0 0 6
1004 (publ) (EUR) 3 HA Post Processor 0 0 5
1004 (publ) (EUR) 4 Datastage GL 3 0 10
1004 (publ) (EUR) 5 Datastage Recon 1 0 3
1004 (publ) (EUR) 11 SAP GL 0 0 4
1004 (publ) (EUR) 21 SAP BW 0 0 4
but I want the output to be :
COMPANYCODE SYSTEM1 SYSTEM2 SYSTEM3 SYSTEM4 SYSTEM5 SYSTEM6 SYSTEM7 SYSTEM8 … SYSTEM N
-------------------------------------------------- --------------------------- ------------------- ----------------------- ------------------------------ ------------------------------ -------------------- -------------- -------------- -------------- --------------
1001 Helsinki Branch GAP 2 / Datastage GL SAP GL SAP BW
1002 Copenhagen Branch GAP 2 / Datastage GL SAP GL SAP BW
1003 Oslo Branch GAP 2 / Datastage GL SAP GL SAP BW
1004 (publ) (EUR) EKO HA Core HA Post Processor Datastage GL Datastage Recon SAP GL SAP BW
Any hint for the above will be highly appreciated.
Thank You
vinayak
Try that:
select companycode, COLLECT(system) as systems
from table_system
where id = (select max(id) from table_system)
group by companycode
order by companycode, sequence
You can use a pivot operation for this; but can't have an unknown number of systems to handle (as you need to know the number of selected columns at parse time):
select * from
(
select companycode, system,
row_number() over (partition by id, country, companycode
order by sequence) as rn
from table_system
where id = (select max(id) from table_system)
)
pivot (max(system) for rn in (1 as system1, 2 as system2, 3 as system3,
4 as system4, 5 as system5, 6 as system6, 7 as system7, 8 as system8))
order by company code;
COMPANYCODE SYSTEM1 SYSTEM2 SYSTEM3 SYSTEM4 SYSTEM5 SYSTEM6 SYSTEM7 SYSTEM8
-------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- --------------------------------------------------
1001 Helsinki Branch GAP 2 / Datastage GL SAP GL SAP BW
1002 Copenhagen Branch GAP 2 / Datastage GL SAP GL SAP BW
1003 Oslo Branch GAP 2 / Datastage GL SAP GL SAP BW
1004 (publ) (EUR) EKO HA Core HA Post Processor Datastage GL Datastage Recon SAP GL SAP BW
So you'd need to establish the maximum number of systems you'll ever have present, and add clauses to the pivot (9 as system9, ...) to accommodate them all. The row_number() translates the sequence numbers into a contiguous number, so you don't have a big gap between the 5th and 6th systems for company 1004; apart from anything else you'd need the pivot to handle the maximum possible sequence number rather than the maximum count of systems.

Resources