Group Specific set of data by Day - sql

Need to get a certain subgroup of data per day (Separated by weekday)
For example
Select weekday,bla,blabla,blablabla from dbo.blabla
where bla = #StartDate
and bla <=#endDate
I need the output to be:
Monday bla blabla blablabla
Tuesday bla blabla blablabla
If someone could help me that would be awesome.

Try to use DATENAME with DW
Something like
SELECT DATENAME(DW, GETDATE())
You can then try something like
DECLARE #Table TABLE(
VAL FLOAT,
DateVal DATETIME
)
INSERT INTO #Table SELECT 1, '01 Jan 2010'
INSERT INTO #Table SELECT 2, '02 Jan 2010'
INSERT INTO #Table SELECT 3, '03 Jan 2010'
INSERT INTO #Table SELECT 4, '08 Jan 2010'
INSERT INTO #Table SELECT 5, '09 Jan 2010'
SELECT DATENAME(DW,DateVal),
SUM(VAL)
FROM #Table
GROUP BY DATENAME(DW,DateVal)

Related

Is Follow-up record created within 7 days?

I have the following sample data, and what I'm trying to determine is show the ClientIDs where a Schedule record has a DateCompleted value, but has not had a Complete Type record created within 7 days.
Based off the below data, ClientID 1 only would be returned.
Create Table #temp
(
ClientID int,
Type varchar(50),
DateCreated datetime,
DateCompleted datetime
)
insert into #temp
(
ClientID,
Type,
DateCreated,
DateCompleted
)
select
1,
'Schedule',
'01 Oct 2020',
'20 Oct 2020'
union all
select
2,
'Schedule',
'15 Oct 2020',
'01 Nov 2020'
union all
select
4,
'Schedule',
'15 Oct 2020',
'01 Nov 2020'
union all
select
4,
'Complete',
'02 Nov 2020',
'02 Nov 2020'
union all
select
5,
'Schedule',
'15 Sep 2020',
'25 Sep 2020'
union all
select
5,
'Complete',
'02 Oct 2020',
'02 Oct 2020'
union all
select
5,
'Schedule',
'15 Oct 2020',
NULL
If I understand correctly, ids 1 and 1 should both be returned.
The following returns all clients with a valid schedule complete time, but no "completed" record within 7 days:
select distinct t.clientId
from temp t
where t.type = 'Schedule' and
t.datecompleted is not null and
not exists (select 1
from temp t2
where t2.clientid = t.clientid and
t2.type = 'Complete' and
datediff(day, t.datecompleted, t2.datecompleted) <= 7
);
Here is a db<>fiddle.
EDIT:
Based on your comment, you need a comparison to the current date:
select distinct t.clientId
from temp t
where t.type = 'Schedule' and
t.datecompleted < dateadd(day, -7, getdate()) and
not exists (select 1
from temp t2
where t2.clientid = t.clientid and
t2.type = 'Complete' and
datediff(day, t.datecompleted, t2.datecompleted) <= 7
);
As far as I can understand that you can use DATEDIFF() function with day as the first argument
SELECT *,
CASE WHEN DATEDIFF(day, DateCreated, DateCompleted ) <= 7 THEN
'Yes'
ELSE
'No'
END AS "Completed IN One Week"
FROM #temp
Update : depending on the comment; need to see whether there is an associated "Complete" row use this query :
SELECT ClientID
FROM #temp
GROUP BY ClientID
HAVING SUM(CASE WHEN Type='Complete' THEN 1 END)>0
Demo
Phillip, I hope this will help you.
Select * from #temp where datecompleted is not null and type='Schedule' and datediff(d,datecompleted,getdate())>7 and clientid not in (select distinct Clientid from #temp where type='Complete')

SQL Server 2008

Sorry for my English...
I Iave a table with column
project, month, year
abc 2 2017
xyz 5 2017
abc 3 2017
abc 5 2017
abc 1 2018
How can I search project abc with month = 2 year = 2017 until month = 1 year = 2018
As far as I know, SQL Server 2008 cannot use concat function
Use math comparison:
SELECT * FROM table1
WHERE (year * 12 + month) BETWEEN (2017 * 12 + 1) AND (2018 * 12 + 1)
Try this:
Select *
From YourTable
Where DATETIMEFROMPARTS(year, month, 1, 1, 1, 1, 1)
between '2017-02-01' And '2018-01-01'
I have edited the code to account for the leading zero in the month.
Declare #temp Table
(
project varchar(50),
month int,
year int
);
Insert Into #temp
(project, month, year)
Values ('abc', 2, 2017)
Insert Into #temp
(project, month, year)
Values ('xyz', 5, 2017)
Insert Into #temp
(project, month, year)
Values ('abc', 3, 2017)
Insert Into #temp
(project, month, year)
Values ('abc', 5, 2017)
Insert Into #temp
(project, month, year)
Values ('abc', 1, 2018)
Insert Into #temp
(project, month, year)
Values ('xxx', 5, 2010)
Insert Into #temp
(project, month, year)
Values ('xxx', 12, 2018)
Declare #FromYear int = 2010;
Declare #FromMonth int = 04;
Declare #ToYear int = 2018;
Declare #ToMonth int = 05;
Select *
From #temp
Where Convert(varchar, year) + right('00' + Convert(varchar, month), 2) Between '201004' and '201805'
How can I search project abc with month = 2 year = 2017 until month = 1 year = 2018
You can use
SELECT *
FROM T
WHERE (([Year] * 10) + [Month]) BETWEEN 20172 AND 20181
AND
project = 'abc';
Demo

TSQL Recursive CTE - get child record id up to a certain point

I have the below recordset that I am trying to get a list of linked IDs from given the parent ID.
DECLARE #TableVals TABLE
([ID] NVARCHAR(5),
[NewId] NVARCHAR(5),
[LinkDate] DATETIME,
[IsUnlink] BIT);
INSERT INTO #TableVals
VALUES ('00899', '00897', '01 Jan 2012 13:46:30', 0),
('00900', '00903', '01 Jan 2012 12:05:16', 0),
('00901', '00903', '01 Jan 2012 11:03:13', 1),
('00903', '00897', '01 Jan 2012 11:01:57', 0),
('00902', '00903', '01 Jan 2012 10:44:00', 0),
('00898', '00906', '01 Jan 2012 10:34:36', 1),
('00895', '00897', '01 Jan 2012 10:25:51', 0),
('00893', '00897', '01 Jan 2012 10:25:33', 0),
('00891', '00897', '01 Jan 2012 10:24:48', 0)
I have this CTE which returns two unexpected values (00900 and 00902), as these are linked to 00903 which was unlinked from. I've attempted to factor in a check on LinkDate but I suspect I've not got it quite right.
DECLARE #ID NVARCHAR(5) = '00897'
;WITH CurrentLinks AS
(
SELECT
[tv].[ID], [tv].[NewId], [tv].[LinkDate]
FROM
#TableVals [tv]
WHERE
[tv].[NewId] = #ID
AND [tv].[IsUnlink] != 1
UNION ALL
SELECT
[tv].[ID], [tv].[NewId], [tv].[LinkDate]
FROM
#TableVals [tv]
INNER JOIN
CurrentLinks [cl] ON [tv].[NewId] = [cl].[ID]
AND [tv].[IsUnlink] != 1
)
SELECT
[cl].[ID]
FROM
CurrentLinks cl
WHERE
[cl].[id] != #ID
AND NOT EXISTS (SELECT 1
FROM #TableVals tv
WHERE (tv.ID = cl.ID OR tv.NewId = cl.ID)
AND tv.LinkDate > cl.LinkDate)
ORDER BY
[cl].[LinkDate] DESC;
When ID is set to 00903 I expect 00900 and 00902 to be returned, and when ID 00897 is passed in I expect 00899, 00895, 00893 and 00891.
Thanks in advance for any help or direction
I believe your code is fine but your expectations of the expected result is wrong because of your dataset.
This record
('00903', '00897', '01 Jan 2012 11:01:57', 0),
links 00903 to 00897 and then 00903 links to 00900, 00901, and 00902 so you ware appropriately getting those as results when you use recursion.....
could something like this work?
SELECT *
FROM #TableVals tv1
WHERE [NewId] = #ID
AND tv1.IsUnlink <> 1
AND NOT EXISTS ( SELECT 1
FROM #TableVals tv2
WHERE tv2.[NewId] = tv1.[ID]
AND tv2.IsUnlink = 1 )

Datetime selection query group by day

I've got a question for my SQL query I've got too write. It's a long time ago since I've written an query so I could use some help with mine. I've tried looking for examples but didn't find the right result. Ive written an query but its really isn't working for me..
What im trying to do is get the sum of the total power consumption for each date in my database.
My table looks like:
|HistoryProbes|
|-------------|
|id (int) pk |
|timestamp (datetime) formatted as: "yyyy-MM-ddTHH:mm:ss"|
|PowerConsumption (int)|
I've found a sample that did quite work.. But it isnt the best solution for me..
it can be found at : http://cephas.net/blog/2005/12/06/sql-server-group-by-datetime/
So far i got this working
SELECT distinct CONVERT(varchar, timestamp, 111) AS thedate
FROM HistoryProbes
I got values 25/11/2009 and 24/11/2009 but i cant manage to get the sum of the PowerConsumption
Thanks.
Something like this will give you the sum per day
DECLARE #HistoryProbes TABLE(
id INT,
timesmp DATETIME,
PowerConsumption INT
)
INSERT INTO #HistoryProbes (id,timesmp,PowerConsumption) SELECT 1, '01 Jan 2009 12:00:00',1
INSERT INTO #HistoryProbes (id,timesmp,PowerConsumption) SELECT 2, '01 Jan 2009 11:00:00',2
INSERT INTO #HistoryProbes (id,timesmp,PowerConsumption) SELECT 3, '01 Jan 2009 13:00:00',3
INSERT INTO #HistoryProbes (id,timesmp,PowerConsumption) SELECT 4, '01 Jan 2009 14:00:00',4
INSERT INTO #HistoryProbes (id,timesmp,PowerConsumption) SELECT 5, '02 Jan 2009 12:00:00',14
INSERT INTO #HistoryProbes (id,timesmp,PowerConsumption) SELECT 6, '02 Jan 2009 11:00:00',24
INSERT INTO #HistoryProbes (id,timesmp,PowerConsumption) SELECT 7, '03 Jan 2009 13:00:00',34
INSERT INTO #HistoryProbes (id,timesmp,PowerConsumption) SELECT 8, '03 Jan 2009 14:00:00',44
SELECT DATEADD(dd,0, DATEDIFF(dd,0,timesmp)),
SUM(PowerConsumption)
FROM #HistoryProbes
GROUP BY DATEADD(dd,0, DATEDIFF(dd,0,timesmp))
select CONVERT(varchar, timestamp, 111) as timestamp_by_day
, sum(PowerConsumption) as total_power
from HistoryProbes
group by CONVERT(varchar, timestamp, 111)
order by CONVERT(varchar, timestamp, 111)
Try this:
SELECT Convert(varchar, timestamp, 111) as thedate, SUM(PowerConsumption) as Total
FROM HistoryProbes
GROUP BY Convert(varchar, timestamp, 111)
I'm not sure why you need distinct in there; since you're not joining to any other tables

SQL To find difference between multiple rows

I have a table containing multiple records for different transactions i.e.
ID Date REF
1 01/09/2008 A
1 11/09/2008 A
1 01/10/2008 A
2 01/09/2008 A
2 01/10/2008 A
2 01/11/2008 B
2 01/12/2008 B
and I'm looking to summarise the data so that I have the average days for each id and ref...
i.e.
ID Ref Avg_Days
1 A 15
2 A 30
2 B 30
Thanks in advance if anyone can help
Average day difference is a SUM of differences divided by COUNT(*)
SUM of differences is in fact difference between MIN and MAX:
SELECT id, ref, DATEDIFF(day, MIN(date), MAX(date)) / NULLIF(COUNT(*) - 1, 0)
FROM mytable
GROUP BY
id, ref
Something like this... not really sure how this info will help you with anything though.... need more info as to what your trying to average the days for.
SELECT ID, REF, AVG(DATEPART(day, [Date]))
FROM dbo.Table1
GROUP BY ID, REF
Reference:
AVG,
DATEPART
Using sql server 2005 try this.
DECLARE #Table TABLE(
ID INT,
Date DATETIME,
Ref VARCHAR(MAX)
)
INSERT INTO #Table (ID,Date,Ref) SELECT 1, '01 Sep 2008', 'A'
INSERT INTO #Table (ID,Date,Ref) SELECT 1, '11 Sep 2008', 'A'
INSERT INTO #Table (ID,Date,Ref) SELECT 1, '01 Oct 2008', 'A'
INSERT INTO #Table (ID,Date,Ref) SELECT 2, '01 Sep 2008', 'A'
INSERT INTO #Table (ID,Date,Ref) SELECT 2, '01 Oct 2008', 'A'
INSERT INTO #Table (ID,Date,Ref) SELECT 2, '01 Nov 2008', 'B'
INSERT INTO #Table (ID,Date,Ref) SELECT 2, '01 Dec 2008', 'B'
;WITH Ordered AS (
SELECT ID,
Ref,
Date,
ROW_NUMBER() OVER (PARTITION BY ID, Ref ORDER BY Date) SubNumber
FROM #Table t
)
SELECT Ordered.ID,
Ordered.Ref,
AVG(DATEDIFF(dd, Ordered.Date, OrderedNext.Date)) AVG_Days
FROM Ordered INNER JOIN
Ordered OrderedNext ON Ordered.ID = OrderedNext.ID
AND Ordered.Ref = OrderedNext.Ref
AND Ordered.SubNumber + 1 = OrderedNext.SubNumber
GROUP BY Ordered.ID,
Ordered.Ref
Also have a look at it mathematically:
Let say
([X(1)-X(0)] + [X(2)-X(1)] + [X(3)-X(2)] + ... + [X(n-1)-X(n-2)] + [X(n)-X(n-1)]) / (n-1).
expand the top part as
-X(0) + X(1) - X(1) + X(2) - X(2) + X(3) - ... - X(n-2) + X(n-1) - X(n-1) + X(n)
whcih end up as -X(0) + X(n)
so we have [X(n) - X(0)] / (n - 1)
so take (MAX - MIN) / (Count - 1) for count > 1