I store dates as String in my database, in this format:
YYYY-MM-DD HH:MM
and in my db I have rows (all columns are strings):
COL1 | COL2
----------------------------------
'2012-06-21 18:53' | 'item1'
'2012-06-21 18:54' | 'item2'
'2012-06-21 18:55' | 'item3'
Now I want to compare these stored dates (well, strings), and this is very very strange:
this query
select *
from MyTable
where col1 > Datetime('2012-06-21 18:53')
returns 2 rows (all except first) - this is correct.
but this query
select *
from MyTable
where col1 >= Datetime('2012-06-21 18:53')
return also only 2 rows, but it should return all 3 rows, as I used >= instead of >.
What did I wrong?
sqlite> SELECT datetime('2012-06-21 18:53');
2012-06-21 18:53:00
datetime() returns a string in a different format than the fields of your database. You can use just the string for WHERE, e.g.
select *
from MyTable
where col1 >= '2012-06-21 18:53'
Related
I have a table with more than 15 columns. 2 of of them are of the type varchar, and most of them of type int and float.
I am new to SQL and am trying to figure out a way by which I can check if any of the columns have a NULL value in it.
Had there been just 4 or 5 columns I could have checked them individually with
SELECT COUNT(*) FROM table_name WHERE col1 IS NULL OR col2 IS NULL OR col3 IS NULL ...
But is there any efficient way to do this on a lot of columns in SQLite specifically?
I have referred to other questions regarding this here but I cannot use xml or store anything. Also I am using SQLite and can only run a query.
There is no way (that I know of) to check all columns if they contain null without explicitly listing all the column names.
Your query is the proper way to do it.
If you want to shorten (not significantly) the code you could use these alternatives:
SELECT COUNT(*) FROM table_name WHERE col1 + col2 + col3 IS NULL;
or:
SELECT COUNT(*) FROM table_name WHERE col1 || col2 || col3 IS NULL;
or:
SELECT COUNT(*) FROM table_name WHERE MAX(col1, col2, col3) IS NULL;
The above queries work, for any data type of the columns, because if there is even only 1 column equal to null then addition, concatenation and the scalar function MAX() (and MIN()) all return null.
See the demo.
Let's suppose I have data like
column
ABC
ABC PQR
ABC (B21)
XYZ ABC
and I wanted output as first string i.e.
ABC
XYZ
i.e. group by column
but I could not able to remove string after space.
I believe that the following would do what you want :-
SELECT * FROM mytable GROUP BY CASE WHEN instr(mycolumn,' ') > 0 THEN substr(mycolumn,1,instr(mycolumn,' ')-1) ELSE mycolumn END;
obviously table and column name changed appropriately.
As an example, using your data plus other data to demonstrate, the following :-
DROP TABLE IF EXISTS mytable;
CREATE TABLE IF NOT EXISTS mytable (mycolumn);
INSERT INTO mytable VALUES ('ABC'),('ABC PQR'),('ABC (B21)'),('XYZ'),('A B'),('AAAAAAAAAAAAAAAAAAAAAAAA B'),(' ABC'),(' XZY');
SELECT * FROM mytable;
SELECT *,group_concat(mycolumn) FROM mytable GROUP BY CASE WHEN instr(mycolumn,' ') > 0 THEN substr(mycolumn,1,instr(mycolumn,' ')-1) ELSE mycolumn END;
DROP TABLE IF EXISTS mytable;
group_concat added to show the columns included in each group
Produces:-
The ungrouped table (first SELECT):-
The grouped result (plus group_concat column) :-
the first row being grouped due to the first character being a space in ABC and XZY
You don't want to do any aggregation, so there is no need for a GROUP BY clause.
Use string functions like SUBSTR() and INSTR() to get the 1st word of each string and then use DISTINCT to remove duplicates from the results:
SELECT DISTINCT SUBSTR(columnname, 1, INSTR(columnname || ' ', ' ') - 1) new_column
FROM tablename
See the demo.
Results:
new_column
ABC
XYZ
I have a single column with comma separated values like below.
sel job_dependency from test_table;
job_dependency
1;2;3;4;5;6
I need to convert it into below format in Teradata SQL where each number is a row.
job_dependency
1
2
3
4
5
6
Any help would be really helpful.
There's a table function for this task:
WITH cte AS
(
SELECT
1 AS inKey -- might be a column, either INT or VarChar up to 60 bytes
-- Other data types should be CASTed to VarChar (and back in the Select)
,job_dependency2 AS inString
FROM test_table
)
SELECT *
FROM TABLE
( StrTok_Split_To_Table(cte.inKey, cte.inString, ';')
RETURNS (outKey INTEGER, -- data type must match input column
tokenNum INTEGER,
token VARCHAR(20))
) AS dt
I have a table with feilds like
TimeStamp | Feild1 | Feild 2
--------------------------------------
1902909002 | xyddtz | 233447
1902909003 | xytzff | 233442
1902909005 | xytzdd | 233443
1902909007 | xytzdd | 233443
1902909009 | xytsqz | 233436
Now i want to query it and fetch records like between 1902909002 and 1902909007 which will be easily done with :
Select * from table where timestamp > 1902909001 AND timestamp < 1902909008
but two more things i want to do is :
maybe that particular time stamp is not there so i have to find nearest value
like if there are 200 records in that range but i want to fetch only 20 so i want to skip every 19 records in a row and fetch 20th, 40th etc records.
i will be having date in datetime format. i know i can convert it before querying but if there is some option in query itself then it willbe better.
Try this query
select * from(
select #rn:=if(#rn < rid, rid, #rn) as rn, rid, timestamp, feild1, feild2
from
(select #rn:=#rn+1 as rId, tbl.*
from tbl
join
(select #rn:=0) tmp
where timestamp between 1902909002 and 1902909024 order by rid desc)a
join
(select #rn:=0)tmp)tmp
where rid%(rn div 6)=0
SQL FIDDLE
Try this (it is crucial for both queries to be exec in the same mysql session):
SET #c:=0;
SELECT
*
FROM (
SELECT
* ,
#c:=#c+1 as counter
FROM
table
WHERE
timestamp > 1902909001
AND timestamp < 1902909008
) as tmp
WHERE
counter % 20 =1;
I'm adding an 'index' column to a table in SQLite3 to allow the users to easily reorder the data, by renaming the old database and creating a new one in its place with the extra columns.
The problem I have is that I need to give each row a unique number in the 'index' column when I INSERT...SELECT the old values.
A search I did turned up a useful term in Oracle called ROWNUM, but SQLite3 doesn't have that. Is there something equivalent in SQLite?
You can use one of the special row names ROWID, OID or _ROWID_ to get the rowid of a column. See http://www.sqlite.org/lang_createtable.html#rowid for further details (and that the rows can be hidden by normal columns called ROWID and so on).
Many people here seems to mix up ROWNUM with ROWID. They are not the same concept and Oracle has both.
ROWID is a unique ID of a database ROW. It's almost invariant (changed during import/export but it is the same across different SQL queries).
ROWNUM is a calculated field corresponding to the row number in the query result. It's always 1 for the first row, 2 for the second, and so on. It is absolutely not linked to any table row and the same table row could have very different rownums depending of how it is queried.
Sqlite has a ROWID but no ROWNUM. The only equivalent I found is ROW_NUMBER() function (see http://www.sqlitetutorial.net/sqlite-window-functions/sqlite-row_number/).
You can achieve what you want with a query like this:
insert into new
select *, row_number() over ()
from old;
No SQLite doesn't have a direct equivalent to Oracle's ROWNUM.
If I understand your requirement correctly, you should be able to add a numbered column based on ordering of the old table this way:
create table old (col1, col2);
insert into old values
('d', 3),
('s', 3),
('d', 1),
('w', 45),
('b', 5465),
('w', 3),
('b', 23);
create table new (colPK INTEGER PRIMARY KEY AUTOINCREMENT, col1, col2);
insert into new select NULL, col1, col2 from old order by col1, col2;
The new table contains:
.headers on
.mode column
select * from new;
colPK col1 col2
---------- ---------- ----------
1 b 23
2 b 5465
3 d 1
4 d 3
5 s 3
6 w 3
7 w 45
The AUTOINCREMENT does what its name suggests: each additional row has the previous' value incremented by 1.
I believe you want to use the constrain LIMIT in SQLite.
SELECT * FROM TABLE can return thousands of records.
However, you can constrain this by adding the LIMIT keyword.
SELECT * FROM TABLE LIMIT 5;
Will return the first 5 records from the table returned in you query - if available
use this code For create Row_num 0....count_row
SELECT (SELECT COUNT(*)
FROM main AS t2
WHERE t2.col1 < t1.col1) + (SELECT COUNT(*)
FROM main AS t3
WHERE t3.col1 = t1.col1 AND t3.col1 < t1.col1) AS rowNum, * FROM Table_name t1 WHERE rowNum=0 ORDER BY t1.col1 ASC