Find Records in SQL not having a particular value - sql-server

Hi All I need a help finding a query that will get all records form my table
where it does not contain a pair alarmtype where its value is 'RETURN' and another value heres my table:
AlarmType Day PointName
SENSOR 2017-09-02 00:00:00.000 20CHB01CE104XG95.UNIT2#NET0
RETURN 2017-09-02 00:00:00.000 20CHB01CE104XG95.UNIT2#NET0
RETURN 2017-09-02 00:00:00.000 20CHB01CE105XG95.UNIT2#NET0
SENSOR 2017-09-02 00:00:00.000 20CHB01CE105XG95.UNIT2#NET0
RETURN 2017-09-02 00:00:00.000 20CHB01CE106XG95.UNIT2#NET0
SENSOR 2017-09-02 00:00:00.000 20CHB01CE106XG95.UNIT2#NET0
RETURN 2017-09-02 00:00:00.000 20CHB01CE107XG95.UNIT2#NET0
SENSOR 2017-09-02 00:00:00.000 20CHB01CE107XG95.UNIT2#NET0
HIGH1 2017-09-02 00:00:00.000 20LBB20CP003.UNIT2#NET0
SENSOR 2017-09-02 00:00:00.000 20MAV10CL011.UNIT2#NET0
Now the answer I am looking for is the last 2 rows since they don't have any 'RETURN' Values
Any help will be greatly appreciated

Try this :
select *
from <table>
where pointName not in (select pointName from <table> where alarmType = 'return');

try this:
SELECT * FROM <table> WHERE alarmtype <> 'RETURN'

Related

MSSQL - split records per week_start and week_end

I have a table similar to the one represented below.
myID | some data | start_date | end_date
1 Tom 2016-01-01 2016-05-09
2 Mike 2015-03-01 2017-03-09
...
I have a function that when provided with start_date, end_date, interval (for example weeks)
returns me data as below. (splits the start and end dates to week intervals)
select * from my_function('2016-01-01','2016-01-12', 'ww')
2015-12-28 00:00:00.000 | 2016-01-03 00:00:00.000 15W53
2016-01-04 00:00:00.000 | 2016-01-10 00:00:00.000 16W1
2016-01-11 00:00:00.000 | 2016-01-17 00:00:00.000 16W2
I would like to be able to write a query that returns all of the values from the 1 table, but splits Start date and end date in to multiple rows using the function.
myID | some data | Week_start_date | Week_end_date | (optional)week_num
1 Tom 2015-12-28 2016-01-03 15W53
1 Tom 2016-01-04 2016-01-10 16W1
1 Tom 2016-01-11 2016-01-17 16W2
...
2 Mike etc....
Could someone please help me with creating such a query ?
select myID,some_data,b.Week_start_date,b.Week_end_date,b.(optional)week_num from #a cross apply
(select * from my_function('2016-01-01','2016-01-12', 'ww'))b
like sample data i tried
create table #a
(
myID int, some_data varchar(50) , start_date date, end_date date)
insert into #a values
(1,'Tom','2016-01-01','2016-05-09'),
(2,'Mike','2015-03-01','2017-03-09')
here iam keeping function result into one temp table
create table #b
(
a datetime,b datetime, c varchar(50)
)
insert into #b values
('2015-12-28 00:00:00.000','2016-01-03 00:00:00.000','15W53'),
('2016-01-04 00:00:00.000','2016-01-10 00:00:00.000','16W1 '),
('2016-01-11 00:00:00.000','2016-01-17 00:00:00.000','16W2 ')
select myID,some_data,b.a,b.b,b.c from #a cross apply
(select * from #b)b
output like this
myID some_data a b c
1 Tom 2015-12-28 00:00:00.000 2016-01-03 00:00:00.000 15W53
1 Tom 2016-01-04 00:00:00.000 2016-01-10 00:00:00.000 16W1
1 Tom 2016-01-11 00:00:00.000 2016-01-17 00:00:00.000 16W2
2 Mike 2015-12-28 00:00:00.000 2016-01-03 00:00:00.000 15W53
2 Mike 2016-01-04 00:00:00.000 2016-01-10 00:00:00.000 16W1
2 Mike 2016-01-11 00:00:00.000 2016-01-17 00:00:00.000 16W2
Based on your current result and expected result,the only difference ,i see is myID
so you will need to frame your query like this..
;with cte
as
(
select * from my_function('2016-01-01','2016-01-12', 'ww')
)
select dense_rank() over (order by somedata) as col,
* from cte
Dense Rank assigns same values for the same partition and assigs the sequential value to next partition ,unlike Rank
Look here for more info:
https://stackoverflow.com/a/7747342/2975396

Recursive CTE to split date range

I need to extract and split data from a membership table.
I want to split the range to get one line per year.
DateFrom and dateTo can be any day of the year but when dates are split, we assume that a row ends on december 31 and a new row start on january 1st
Here's a look of the data
membershipId - groupId - ClientId - DateFrom - DateTo
2707 20008 1579 1997-01-01 00:00:00.000 1997-12-31 00:00:00.000
20989 20008 1579 1999-01-01 00:00:00.000 2004-12-31 00:00:00.000
39874 20298 1579 2005-01-01 00:00:00.000 2008-12-31 00:00:00.000
50295 21661 1579 2009-01-01 00:00:00.000 2009-12-31 00:00:00.000
50988 20399 1579 2010-01-01 00:00:00.000 2010-12-31 00:00:00.000
52378 21661 1579 2011-01-01 00:00:00.000 2013-12-31 00:00:00.000
57274 21660 1579 2014-01-01 00:00:00.000 3000-01-01 00:00:00.000
The expected result is : (every range split)
2707 20008 1579 1997-01-01 00:00:00.000 1997-12-31 00:00:00.000
20989 20008 1579 1999-01-01 00:00:00.000 1999-12-31 00:00:00.000
20989 20008 1579 2000-01-01 00:00:00.000 2000-12-31 00:00:00.000
20989 20008 1579 2001-01-01 00:00:00.000 2001-12-31 00:00:00.000
20989 20008 1579 2002-01-01 00:00:00.000 2002-12-31 00:00:00.000
20989 20008 1579 2003-01-01 00:00:00.000 2003-12-31 00:00:00.000
20989 20008 1579 2004-01-01 00:00:00.000 2004-12-31 00:00:00.000
50295 21661 1579 2009-01-01 00:00:00.000 2009-12-31 00:00:00.000
50988 20399 1579 2010-01-01 00:00:00.000 2010-12-31 00:00:00.000
52378 21661 1579 2011-01-01 00:00:00.000 2011-12-31 00:00:00.000
52378 21661 1579 2012-01-01 00:00:00.000 2012-12-31 00:00:00.000
52378 21661 1579 2013-01-01 00:00:00.000 2013-12-31 00:00:00.000
57274 21660 1579 2014-01-01 00:00:00.000 3000-01-01 00:00:00.000
I tried to use recursive CTE based on this :
Possible recursive CTE query using date ranges
But I cannot achieve the desired result.
I made this query :
WITH splitDates(startDate,endDate, newDate,client, groupingId ) as
(
SELECT m.datefrom as startDate, m.dateTo
, CASE
when year(m.dateFrom) <> year(m.dateto) then CAST(CAST(year(m.dateFrom) AS varchar) + '-' + CAST(12 AS varchar) + '-' + CAST(31 AS varchar) AS DATETIME)
else m.dateTo
end
, m.legalEntityId, m.groupingId
from adesse.dbo.membership m
UNION ALL
SELECT DATEADD(year, 1, startDate),
CAST(CAST(year(startDate)+1 AS varchar) + '-' + CAST(12 AS varchar) + '-' + CAST(31 AS varchar) AS DATETIME)
,CAST(CAST(year(startDate)+1 AS varchar) + '-' + CAST(12 AS varchar) + '- ' + CAST(31 AS varchar) AS DATETIME)
,client, groupingId
FROM splitDates
WHERE year(startDate) <> year(endDate)
)
SELECT *
FROM splitDates
where client = 1579
order by startDate
But the result is incomplete :(
startDate endDate newDate client groupingId
1997-01-01 00:00:00.000 1997-12-31 00:00:00.000 1997-12-31 00:00:00.000 1579 20008
1999-01-01 00:00:00.000 2004-12-31 00:00:00.000 1999-12-31 00:00:00.000 1579 20008
2000-01-01 00:00:00.000 2000-12-31 00:00:00.000 2000-12-31 00:00:00.000 1579 20008
2005-01-01 00:00:00.000 2008-12-31 00:00:00.000 2005-12-31 00:00:00.000 1579 20298
2006-01-01 00:00:00.000 2006-12-31 00:00:00.000 2006-12-31 00:00:00.000 1579 20298
2009-01-01 00:00:00.000 2009-12-31 00:00:00.000 2009-12-31 00:00:00.000 1579 21661
2010-01-01 00:00:00.000 2010-12-31 00:00:00.000 2010-12-31 00:00:00.000 1579 20399
2011-01-01 00:00:00.000 2013-12-31 00:00:00.000 2011-12-31 00:00:00.000 1579 21661
2012-01-01 00:00:00.000 2012-12-31 00:00:00.000 2012-12-31 00:00:00.000 1579 21661
2014-01-01 00:00:00.000 3000-01-01 00:00:00.000 2014-12-31 00:00:00.000 1579 21660
2015-01-01 00:00:00.000 2015-12-31 00:00:00.000 2015-12-31 00:00:00.000 1579 21660
Thx for the help
I'm not sure if your last date is suppose to be 3000-01-01 but this should work
CREATE TABLE members (membershipId INT, groupId INT, clientId INT, dateFrom DATETIME, dateTo DATETIME)
INSERT INTO members VALUES
(2707, 20008, 1579, '1997-01-01 00:00:00.000', '1997-12-31 00:00:00.000'),
(20989, 20008, 1579, '1999-01-01 00:00:00.000', '2004-12-31 00:00:00.000'),
(39874, 20298, 1579, '2005-01-01 00:00:00.000', '2008-12-31 00:00:00.000'),
(50295, 21661, 1579, '2009-01-01 00:00:00.000', '2009-12-31 00:00:00.000'),
(50988, 20399, 1579, '2010-01-01 00:00:00.000', '2010-12-31 00:00:00.000'),
(52378, 21661, 1579, '2011-01-01 00:00:00.000', '2013-12-31 00:00:00.000'),
(57274, 21660, 1579, '2014-01-01 00:00:00.000', '3000-01-01 00:00:00.000')
;
WITH cte AS
(
SELECT
membershipId,
groupId,
clientId,
dateFrom,
DATEADD(day, -1, DATEADD(YEAR,1,dateFrom)) newDateTo,
dateTo
FROM
members
UNION ALL
SELECT
m.membershipId,
m.groupId,
m.clientId,
DATEADD(YEAR,1,c.dateFrom),
DATEADD(day, -1, DATEADD(YEAR,2,c.dateFrom)),
c.dateto
FROM
members m
JOIN cte c ON c.membershipId = m.membershipId
AND DATEADD(YEAR,1,c.dateFrom) < m.dateTo
)
SELECT
membershipId,
groupId,
clientId,
dateFrom,
newDateTo dateTo
FROM
cte
ORDER BY
membershipId, dateFrom
OPTION (MAXRECURSION 0);
DROP TABLE members
SQL Fiddle

SQL DATEFROMPARTS - Fails on YEAR(GETDATE())

I'm trying to create several date variables based on an original value, but with the current year. The only code I can get to run seems overly complex and gives me inaccurate results:
, DATEADD(DAY,DATEPART(DAYOFYEAR, o.AnnualReviewDate),
DATEADD(YEAR,YEAR(GETDATE())-1900,0)) AS ARDateCurr
DATEADD(DAY,DATEPART(DAYOFYEAR, o.AnnualReviewDate)+30,
DATEADD(YEAR,YEAR(GETDATE())-1900,0)) AS ARDatePlus30
Why does:
DECLARE #Now AS DATE = GETDATE()
DECLARE #Year AS INT = DATEPART(YEAR,#Now)
...
, DATEFROMPARTS(YEAR(#Now),MONTH(o.AnnualReviewDate)-1,
DAY(o.AnnualReviewDate)) AS ARDateMin30
give me the error message:
'Cannot construct data type date, some of the arguments have values which are not valid.'
At a guess, are these the values you're looking for:
declare #t table (AnnualReviewDate datetime)
insert into #t (AnnualReviewDate) values
('20121004'),('20090924'),('20101007'),('20141008'),('20090508'),
('20120229')
select
AnnualReviewDate,
r.ARCurrDue,
DATEADD(day,-30,ARCurrDue) as ARDateMin30,
DATEADD(day,30,ARCurrDue) as ARDatePlus30
from #t t
cross apply (SELECT DATEADD(year,DATEDIFF(year,AnnualReviewDate,GETDATE())
,AnnualReviewDate) as ARCurrDue) r
Results:
AnnualReviewDate ARCurrDue ARDateMin30 ARDatePlus30
----------------------- ----------------------- ----------------------- -----------------------
2012-10-04 00:00:00.000 2015-10-04 00:00:00.000 2015-09-04 00:00:00.000 2015-11-03 00:00:00.000
2009-09-24 00:00:00.000 2015-09-24 00:00:00.000 2015-08-25 00:00:00.000 2015-10-24 00:00:00.000
2010-10-07 00:00:00.000 2015-10-07 00:00:00.000 2015-09-07 00:00:00.000 2015-11-06 00:00:00.000
2014-10-08 00:00:00.000 2015-10-08 00:00:00.000 2015-09-08 00:00:00.000 2015-11-07 00:00:00.000
2009-05-08 00:00:00.000 2015-05-08 00:00:00.000 2015-04-08 00:00:00.000 2015-06-07 00:00:00.000
2012-02-29 00:00:00.000 2015-02-28 00:00:00.000 2015-01-29 00:00:00.000 2015-03-30 00:00:00.000
That is, ARCurrDue should be the same day and month as AnnualReviewDate, but in the current year, and then the other columns are plus and minus 30 days from that?
You'll note I've included a 29th February in the sample so you can see what's computed for it (you should always think about what the requirement is for such dates and include them in sample data)
The magic here is using this expression to reset a date's year to the current one, without affecting the month and day (except for Feb 29):
DATEADD(year,DATEDIFF(year,AnnualReviewDate,GETDATE())
,AnnualReviewDate)
The inner expression (DATEDIFF) is "how many year boundaries have passed since AnnualReviewDate". The outer expression then adds that same number of whole years onto AnnualReviewDate. Note that this same expression even works if AnnualReviewDate is a date in the future.
You shouldn't use integer operations in a DATETIME calculation. Do this instead:
DATEFROMPARTS(YEAR(#Now),MONTH(DATEADD(M,-1,o.AnnualReviewDate)),DAY(o.AnnualReviewDate)) AS ARDateMin30

How to delete the duplicate based on date

I have a table where I have several cust_id duplicates. I would like to keep the row where prendate_next is nearest to the current date and delete the rest of the duplicates. Please help me how. I am new to this
cust_id prendate_next
1000105737 2014-11-30 00:00:00.000
1000105836 2014-11-20 00:00:00.000
1000143646 2014-11-10 00:00:00.000
1000143646 2015-03-09 00:00:00.000
1000179487 2014-12-05 00:00:00.000
1000182253 2015-01-01 00:00:00.000
1000192740 2014-10-02 00:00:00.000
1000192740 2015-01-10 00:00:00.000
1000199419 2015-09-30 00:00:00.000
1000170578 2014-12-26 00:00:00.000
1000188890 2015-06-23 00:00:00.000
1000189075 2015-03-01 00:00:00.000
1000189075 2015-03-01 00:00:00.000
1000189144 2015-04-04 00:00:00.000
;WITH cte AS (
SELECT cust_id, prendate_next,
ROW_NUMBER() OVER (PARTITION BY cust_id ORDER BY ABS(DATEDIFF(DAY,prendate_next,GETDATE()))) AS RowNumber
FROM MyTable
)
DELETE MyTable
FROM MyTable
INNER JOIN cte ON MyTable.cust_id = cte.cust_id
AND MyTable.prendate_next = cte.prendate_next
WHERE cte.RowNumber != 1
ABS(DATEDIFF(DAY,prendate_next,GETDATE())) counts how many days prendate_next is from today.

Handle condition in select statement

I have a table like this:
customer:
customerID joineddate
111 2004-12-10 00:00:00.000
111 2004-12-10 00:00:00.000
111 2004-12-10 00:00:00.000
211 2004-12-10 00:00:00.000
231 2004-12-10 00:00:00.000
231 2004-11-10 00:00:00.000
411 2008-12-10 00:00:00.000
531 2009-12-10 00:00:00.000
I have written the query from 2 tables where I do a join and get the result like the above. But I need to get the result like this where I need to input my condition and get the result like below.
customerID joineddate indicator
111 2004-12-10 00:00:00.000 3
211 2004-12-10 00:00:00.000 1
231 2004-12-10 00:00:00.000 1
231 2004-11-10 00:00:00.000 1
411 2008-12-10 00:00:00.000 1
531 2009-12-10 00:00:00.000 1
Having absolutely no clue what your other table is named or how it is related to the customer table, here is my best guess:
SELECT c.customerID, o.joineddate, indicator = COUNT(*)
FROM dbo.customer AS c
INNER JOIN dbo.[other table] AS o
ON c.CustomerID = o.CustomerID
GROUP BY c.customerID, o.joineddate;
Google for keyword
GROUP BY
and the
COUNT()
function.

Resources