SQL - Using datediff as a query is running? - sql-server

Its my first post and I'm really rusty on MSSQL so be gentle :-)
I have a table in which I am trying to use datediff. I think it will be easiest if I post the query and results first
select mh.agetime, mh.whatid
from mailhistory mh
inner join mail m
on mh.mailid=m.myid
where (mh.whatid=17 or mh.whatid=11 or mh.whatid=0) and maincontactid=287816 and mailid=276086
order by agetime
Really, the maincontactid and mailid are currently just in there to limit the results while i make the query.
The results are as follows...
AGETIME WHATID
1899-12-30 00:00:00.000 0
1899-12-30 00:48:10.000 11
1899-12-31 02:16:49.000 17
1899-12-31 06:29:08.000 11
1900-01-18 15:31:40.000 17
1900-02-11 14:56:59.000 11
I am trying to make a third column as the query runs that will make a third column showing the difference in the dates (in days)... between items with a WHATID of 11 and 17... so I'm after results like this:
AGETIME WHATID DIFFERENCE
1899-12-30 00:00:00.000 0 NULL
1899-12-30 00:48:10.000 11 0
1899-12-31 02:16:49.000 17 1
1899-12-31 06:29:08.000 11 0
1900-01-18 15:31:40.000 17 18
1900-02-11 14:56:59.000 11 22
Something like that... So, is there a way to convert my query to do the running datediff like that?
Many thanks in advance!
Chris

If using SQL Server 2005 or above, you can make a CTE and assign row_number to your current resultset. Then you can have a left self join on CTE with Current.Row_Num = Previous.Row_Num -1 and then can get the date difference. Approach will be similar as show in this link:
http://www.kodyaz.com/articles/sql-select-previous-and-next-rows-with-current-row-in-tsql.aspx
For SQL Server 2000
Assuming there is no grouping in result set:
I would probably create a temp table variable instead of CTE with an Identity Filed( Which will act as a rownumber) and then will apply the same logic as described above for 2005. Only major change will be instead of CTE we will use Temp Table variable and instead of rownumber we will use identity in temp table.

Related

Combine multiple similar columns into single column

I have a table like
Id RefNumber LotNum
---------------------------
1 Ref-1 10
2 Ref-1 11
Lotnumber:
Lot-Id Lot-Name
-------------------
10 Apple
11 Banana
I need my output to look like this:
Ref-1 Apple,Banana
Please help me - how can I achieve this?
On SQL Server 2017 and later, we can use STRING_AGG here:
SELECT
r.RefNumber,
STRING_AGG(l.[Lot-Name]) WITHIN GROUP (ORDER BY l.[Lot-Id]) AS LotNames
FROM Refs r
LEFT JOIN Lotnumber l
ON r.LotNum = l.[Lot-Id]
GROUP BY
r.RefNumber;

SQL Server Get row value when using MAX

I have a table which holds a date field and an integer field like the example below:
Date Number
01/01/2017 9
02/01/2017 13
03/01/2017 16
04/01/2017 2
15/01/2017 4
20/01/2017 8
27/01/2017 1
I want to write a query selecting the MAX(date) where the date is <= 13/01/2017 (which would give me 04/01/2017) and return the number column value associated with it (2 in this example).. I can of course write 2 queries getting one and using the result to find the next but I hope there is another way using only one statement. It probably would help if I knew how to word this so I haven't had much luck searching for a solution..
Thank you in advance..
Derek
Use TOP 1 and Order By
select Top 1 * from yourtable where [date] <= CONVERT(DATE, '13/01/2017', 103)
order by date desc
Better to use yyyy-mm-dd format for your date input

PostgreSQL - Filter column 2 results based on column 1

Forgive a novice question. I am new to postgresql.
I have a database full of transactional information. My goal is to iterate through each day since the first transaction, and show how many unique users made a purchase on that day, or in the 30 days previous to that day.
So the # of unique users on 02/01/2016 should show all unique users from 01/01/2016 through 02/01/2016. The # of unique users on 02/02/2016 should show all unique users from 01/02/2016 through 02/02/2016.
Here is a fiddle with some sample data: http://sqlfiddle.com/#!15/b3d90/1
The result should be something like this:
December 17 2014 -- 1
December 18 2014 -- 2
December 19 2014 -- 3
...
January 13 2015 -- 16
January 19 2015 -- 15
January 20 2015 -- 15
...
The best I've come up with is the following:
SELECT
to_char(S.created, 'YYYY-MM-DD') AS my_day,
COUNT(DISTINCT
CASE
WHEN S.created > S.created - INTERVAL '30 days'
THEN S.user_id
END)
FROM
transactions S
GROUP BY my_day
ORDER BY my_day;
As you can see, I have no idea how I could reference what exists in column one in order to specify what date range should be included in the filter.
Any help would be much appreciated!
I think if you do a self-join, it would give you the results you seek:
select
t1.created,
count (distinct t2.user_id)
from
transactions t1
join transactions t2 on
t2.created between t1.created - interval '30 days' and t1.created
group by
t1.created
order by
t1.created
That said, I think this is going to do form of a cartesian join in the background, so for large datasets I doubt it's very efficient. If you run into huge performance problems, there are ways to make this a lot faster... but before you address that, find out if you need to.
-- EDIT 8/20/16 --
In response to your issue with the performance of this... yes, it's a pig. I admit it. I encountered a similar issue here:
PostgreSQL Joining Between Two Values
The same concept for your example is this:
with xtrans as (
select created, created + generate_series(0, 30) as create_range, user_id
from transactions
)
select
t1.created,
count (distinct t2.user_id)
from
transactions t1
join xtrans t2 on
t2.create_range = t1.created
group by
t1.created
order by
t1.created
It's not as easy to follow, but it should yield identical results, only it will be significantly faster because it's not doing the "glorified cross join."

SQLite Row_Num/ID

I have a SQLite database that I'm trying to use data from, basically there are multiple sensors writing to the database. And I need to join one row to the proceeding row to calculate the value difference for that time period. But the only catch is the ROWID field in the database can't be used to join on anymore since there are more sensors beginning to write to the database.
In SQL Server it would be easy to use Row_Number and partition by sensor. I found this topic: How to use ROW_NUMBER in sqlite and implemented the suggestion:
select id, value ,
(select count(*) from data b where a.id >= b.id and b.value='yes') as cnt
from data a where a.value='yes';
It works but is very slow. Is there anything simple I'm missing? I've tried to join on the time difference possibly, create a view. Just at wits end! Thanks for any ideas!
Here is sample data:
ROWID - SensorID - Time - Value
1 2 1-1-2015 245
2 3 1-1-2015 4456
3 1 1-1-2015 52
4 2 2-1-2015 325
5 1 2-1-2015 76
6 3 2-1-2015 5154
I just need to join row 6 with row 2 and row 3 with row 5 and so forth based on the sensorID.
The subquery can be sped up with an index with the correct structure.
In this case, the column with the equality comparison must come first, and the one with unequality, second:
CREATE INDEX xxx ON MyTable(SensorID, Time);

Use the result of a Select statement result for another query in mssql server 2008

I have a table forms from which I query out a set of result using
SELECT form_id from forms where customer_id = 200.
I get a set of results like
14
67
90
177
289
800
Now I have separate table based on these form id's like form_{form_id}details. I want to look into each of the table based on the form id's obtained and count the number of records. If form{form_id}_details has any record (i.e count(*) as cnt > 0), I want to get the count. I'm using PHP along with mssql server. Can anyone help me in this?

Resources