How to collect pairs of data based on timestamp - sql

I have this table:
What query should I write in order to get all the pairs of inputs that happen in a timeframe of up to 1 minute.
The end results that I need to receive from the above table should be:

I did it in t-sql but I think its not so hard to translate in mysql.
Assuming that timestamp column is of datetime type then this query does what you are asking for (I tested it in t-sql so I created a table variable you have to use your table):
declare #table table (userid int, input varchar(50),timestmp datetime)
insert into #table values(1,'hy','1/19/2017 12:00')
insert into #table values(2,'by','1/19/2017 12:00')
insert into #table values(1,'hy2','1/19/2017 12:01')
insert into #table values(2,'by2','1/19/2017 12:01')
insert into #table values(3,'why','1/19/2017 12:01')
select t1.userid,t1.input,t2.input from #table t1 inner join #table t2 on t1.userid=t2.userid and t1.timestmp=DATEADD(mi,-1,t2.timestmp)

Try this query, it is giving expected output.
SELECT t1.userid,t1.input,t2.input
FROM test_table t1
INNER JOIN test_table t2
ON TIMESTAMPDIFF(MINUTE,t1.timestmp,t2.timestmp) <= 1
AND t1.userid = t2.userid
Note : Replace your table_name with test_table
Ask in case of any doubt.

Related

SQL - update query - update to next date value that is not NULL

I have a bunch of values that are currently on dates with NULL value (i.e. no data available on those particular dates).
How would I go about updating those values to the next date where there is data available?
I have a select query currently which highlights all values that lie on a date with NULL value (or false data defined by a value of less than 0):
select * from table1 a
left join table2 b on a.id=b.id and a.date=b.date --joins dates table to main data set
where a.id in (select c.id from table3 c
left join table4 d on c.id=d.id where c.value = 000000) -- sub query identifying sub set of data I want to use as 'id' list
and a.date is not NULL and a.date > '1900-01-01' --a.date not NULL just identifies illegitimate date values that I don't want to see
and (b.value is NULL or b.value < 0) --identifies legitimate values that fall on dates where there are NULL values or false dates
So this query gives me all values from a chosen data set that fall on dates with false data or NULL values. There are a few more 'where' and 'and' variables I've used in the query but this hopefully gives a good base of understanding.
I would like to update all of these values to the next date in the future that is not NULL (i.e. has legit data).
Just a small example of what I'm thinking: update table1 set date = (assume there would be some sort of select sub query here to define next date value that is not NULL).
Just another note to take into consideration: the next date that the value is not NULL is dynamic - it could be 2 days from given date but it could be 2 years.
/*I would create a variable table #mytab in which I will put sample sample data
with dates and null*/
--Kamel Gazzah
--07/03/2019
declare #mytab as table(id int identity(1,1),mydate date)
insert into #mytab values('01/01/2018')
insert into #mytab values(NULL)
insert into #mytab values('01/05/2018')
insert into #mytab values('01/07/2018')
insert into #mytab values('01/08/2018')
insert into #mytab values(NULL)
insert into #mytab values(NULL)
insert into #mytab values(NULL)
insert into #mytab values('01/08/2018')
select * from #mytab
--First Method with **OUTER APPLY**
update t1 set mydate=t2.mydate
--select t1.*,t2.mydate
from #mytab t1
OUTER APPLY (select top 1 * from #mytab where mydate is not null and id > t1.id order by mydate) t2
where t1.mydate is null
--SCOND METHOD WITH **LEFT OUTER JOIN**
update ta set mydate=tc.mydate
--select ta.id,tc.mydate
from #mytab ta
inner join(
select id1,min(id2) id2 from(
select t1.id id1,t2.id id2,t2.mydate from #mytab t1
left outer join #mytab t2 on t2.id > t1.id and t2.mydate is not null
where t1.mydate is null) v group by id1) tb on ta.id=id1
inner join #mytab tc on tb.id2=tc.id
select * from #mytab
You can solve it using apply
UPDATE T
SET Date = N.Date
FROM yourTable T
OUTER APPLY (
SELECT TOP 1 Date FROM YourTable
WHERE ........
ORDER BY ..........
) N
WHERE T.Date IS NULL

Replace empty values as 0 instead of null while joining two tables in sql

I have join two tables t1 and t2. The output produces some null records since there is no data in the table t2. Instead of showing null I want to show 0 since I have to perform some arithmetic operation in the crystal reports.
please help me.....
sample example
declare #t table (ID int)
declare #t1 table (ID int)
insert into #t (id) values (1)
select t.ID,ISNULL(TT.ID,0)id from #t t
LEFT JOIN #t1 tt
ON t.ID = tt.ID
Use the COALESCE function which automatically replace null values as 0.
Sample
SELECT COALESCE(total_amount, 0) from #Temp1

SQL intersect with other tables, how do I ignore it?

I am trying to run a query given three tables.
DECLARE #TABLE1 TABLE (ID CHAR(2))
DECLARE #TABLE2 TABLE (ID CHAR(2))
DECLARE #TABLE3 TABLE (ID CHAR(2))
INSERT INTO #TABLE1 VALUES('1')
INSERT INTO #TABLE1 VALUES('2')
INSERT INTO #TABLE2 VALUES('1')
--NOTHING in TABLE3
I Need to get only the values that are present and ignore the null table. This doesn't work since TABLE3 has no values.
SELECT ID
FROM #TABLE1
INTERSECT
SELECT ID
FROM #TABLE2
INTERSECT
SELECT ID
FROM #TABLE3
**Result should be 1**
How do I ignore the any table if it's null but keep the other values?
Why not do a union of select distincts from each table, and then group that by ID and select count(*), and select only rows with count(*) equal to the maximum value of count(*) in the result?
It's a bit of a mess of subqueries at this point unfortunately but you should get the logic :)
Intersect is not going to work for you as you can't add conditions to it.
From what I understand you want to select all records where the ID appears in at least 2 of the tables. I am assuming that the ID is unique to each table.
The following works in MS SQL Server:
DECLARE #TABLE1 TABLE (ID CHAR(2))
DECLARE #TABLE2 TABLE (ID CHAR(2))
DECLARE #TABLE3 TABLE (ID CHAR(2))
INSERT INTO #TABLE1 VALUES('1')
INSERT INTO #TABLE1 VALUES('2')
INSERT INTO #TABLE2 VALUES('1')
--NOTHING in TABLE3
;WITH AllValues AS
(
SELECT ID
FROM #TABLE1
UNION ALL
SELECT ID
FROM #TABLE2
UNION ALL
SELECT ID
FROM #TABLE3
)
SELECT ID
FROM AllValues
GROUP BY ID
HAVING COUNT(*) > 1
Maybe... But the design of the system is extremely foreign; a real world example would help understand what you're trying to do.
Select count(*), ID FROM (
Select ID from #table1
UNION
Select ID from #table2
UNION
Select ID from #table3) Derived
Where RowNum =1
GROUP BY ID
ORder by count(*) DESC
Updated where clause was in wrong place

Updating Values of a table from same table without using a select query

My Requirement
Updating Values of a table from same table without using a select query
this query won't effect any rows.
My aim : Update val2 of #table where slno=1 with the value of val2 of slno=2
Is there any other way without doing this method
Declare #val2 nvarchar(50)
select #val2=val2 from #table where slno=2
update #table set val2=#val2 where slno=1
create table #table
(
slno int identity(1,1),
val nvarchar(50),
val2 nvarchar(50)
)
insert into #table(val,val2)values('1',newID())
insert into #table(val,val2)values('1',newID())
insert into #table(val,val2)values('1',newID())
select * from #table
update #table set val2=T.val2
from #table T where slno=1 and T.slno=2
drop table #table
I have lot of records in the table.
So If i am selecting and update it may effect the performance.
Please, provide more info.
Do you have only 2 rows in your table?
Why do you need this kind of update?
I suppose, that your db structure is wrong, but I can't tell exactly, until you explain why do you need this.
Anyway I can suggest a poor way to do this without using select. You can self join the table. It would be better to have addition column, but if you don't have it, how's you should do
UPDATE T1
SET T1.val2 = T2.val2
FROM #table T1 INNER JOIN #table T2
ON T1.slno = 1 AND T2.slno = 2

please help me to create multi insert query

I have got two table
create table t1(cid int, isnews int)
create table t2(nid int,cid int, isnews int)
situations is like this:
if t2 contain t2.cid = t1.cid then the t2.isnews = t1.news and
if t2 not contain cid of t1 then new record should be inserted in t2 and that t1.cid, t1.isnews should be inserted in t2..
and complete table should be done in single query... i have done the updation part but not able to do insertion part..
update query:
UPDATE t22
SET t22.isnews = t11.isnews
FROM t2 AS t22
JOIN t1 AS t11
ON t11.cid= t22.cid
i have prepared below cursor for insert... is it good? :
DECLARE #clntid INT
DECLARE #clntnewsltr INT
DECLARE clientnews CURSOR FOR
SELECT clientid,newsLetter
FROM clients
WHERE clientid NOT IN (SELECT clientid FROM clientprivacy)
OPEN clientnews
FETCH NEXT FROM clientnews INTO #clntid,#clntnewsltr
WHILE ##FETCH_STATUS = 0
BEGIN
INSERT INTO clientprivacy (clientId,tdNewsLetters) VALUES(#clntid, #clntnewsltr)
FETCH NEXT FROM clientnews INTO #clntid,#clntnewsltr
END
CLOSE clientnews
DEALLOCATE clientnews
I think this is the kind of thing you're after:
--INSERT t2 (cid, isnews)
SELECT t1.cid, t1.isnews
FROM t1
LEFT JOIN t2 ON t1.cid = t2.cid
WHERE t2.cid IS NULL
I've commented out the INSERT line - I recommend you run the SELECT on it's own first to check it does give you the correct result (all records from t1 that don't have a matching cid in t2).
I've assumed t2.nid is an IDENTITY column.
You will be so much better off without cursors :) Cursors take MUCH longer to run in large data sets.
It is true you can use a LEFT JOIN, but you can also use a SELECT in your WHERE clause. Most of the time it's a style choice.
CREATE TABLE table1(col_1 int, col_2 int)
CREATE TABLE table2(nid int, col_1 int, col_2 int)
INSERT INTO table2 (col_1,col_2)
SELECT col_1,col_2
FROM table1
WHERE col_1 NOT IN (SELECT col_1 FROM table2)