And OR in same column in sql server - sql

I have a simple table in SQL server 2008.
SELECT TOP lastupdated, remarks FROM table
I want to select the following criteria.
if remarks is 'Others' and DATEDIFF(MINUTE, LastUpdated, GETDATE() ) > 15
then select these rows
Additionally, I want to select following in the same query
if remarks is not 'Others'
then select these rows without waiting for 15 minutes

You can do the following:
select LastUpdated, Remarks
from table
where (remarks = 'Others' and datediff(min, LastUpdated, GETDATE()) > 15)
or remarks != 'Others'
You can adjust the TOP x, according to your needs, since you didn't put it in your question so I didn't know how many rows you needed to select.

A case expression should help you here:
SELECT TOP lastupdated, remarks
FROM mytable
WHERE DATEDIFF(MINUTE, LastUpdated, GETDATE() ) > CASE remarks WHEN 'Others' THEN 15 ELSE -1 END

You should be able to just nest your WHERE clause like this:
SELECT lastupdated , remarks
FROM table
WHERE remarks != 'Others'
OR
(
remarks = 'Others'
AND
DATEDIFF(MINUTE, LastUpdated, GETDATE() ) > 15
)

Just keep first to condition in braces and then add OR condition like below:
SELECT TOP lastupdated , remarks FROM table
WHERE (remarks = 'Others' AND DATEDIFF(MINUTE, LastUpdated, GETDATE()) > 15)
OR remarks <> 'Others'
Hope it helps.

Related

How to write a T-SQL query which can return 0 rows as part of a case statement

I am trying to write a query which checks how many records arrived in the last x days so that I can send out an alert if no new records have arrived in that window.
To that end I want a query which will check the table and return either 1 row stating no files were detected if there is a problem or no rows if everything is ok. The reason I want there to be no rows is because the downstream program will treat any returned rows as an error having been detected and alert accordingly.
select 'Null check' as id,
case when
count(*) > 0 then NULL
else 'No files detected' end as Message
from TABLE where LASTUPDATEDATE > dateadd(d, -1, getdate())
This query works if an error is detected but not in the correct case as it still returns a row. How can I rewrite it so that it doesn't return anything? Thanks!
For performance reasons, I would recommend writing this as:
select 'Null check' as id, 'No files detected' as Message
from (select top (1) t.*
from table t
where lastupdatedate > dateadd(day, -1, getdate())
) t
having count(*) = 0;
This saves SQL Server from actually having to count a bunch of rows if when things are fine.
Seems to be a task for NOT EXISTS:
select 'Null check' as id, 'No files detected' as Message
where not exists
(
select *
from tab
where lastupdatedate > dateadd(day, -1, getdate())
)
The trick is to use having count(*) = 0
select 'Null check' as id, 'No files detected' as Message
from TABLE
where LASTUPDATEDATE > dateadd(d, -1, getdate())
having count(*) = 0
Demo
SQL Fiddle - count() = 0
SQL Fiddle - count() > 0
You can accomplish this with a CASE and subquery:
SELECT [Message] =
CASE
WHEN COALESCE(SELECT COUNT(*) FROM [TABLE] WHERE [LASTUPDATEDATE] > DATEADD(d, -1, GETDATE())), 0) > 0
THEN 'No files detected'
ELSE NULL
END ;

How to use the result of a SELECT in Table A, to limit the SELECT of Table B using IN

I tried to use the result of a SELECT inside of the IN operator of another SELECT but it takes 15 minutes, but if I run the queries(Query1 and Query 2 below) separate I have results in 2 minutes approximate
I tried to use the result of a SELECT inside of the IN clause of another SELECT but it's really slow
Query 1 takes 1 minute
SELECT Id_A
FROM [Database]..[Table_A]
WHERE location = 'US'
AND datetime_in >= DATEADD(DAY,-30,GETDATE())
AND (
CASE WHEN date_sent IS NULL THEN DATEDIFF(hh, datetime_in, GETDATE())
WHEN date_sent IS NOT NULL THEN DATEDIFF(hh, datetime_in, ship_date)
ELSE 0 END) > 120
Query 2 takes 10 seconds
SELECT *
FROM [Database]..[Table_B]
WHERE Id_B IN (HERE I INSERT MANUALLY ALL THE Table_A..Id_A)
Query 3 taking more then 15 minutes this is the one giving me issues
SELECT *
FROM [Database]..[Table_B]
WHERE Id_B IN (SELECT Id_A
FROM [Database]..[Table_A]
WHERE location = 'US'
AND datetime_in >= DATEADD(DAY,-30,GETDATE())
AND (CASE WHEN date_sent IS NULL
THEN DATEDIFF(hh, datetime_in, GETDATE())
WHEN date_sent IS NOT NULL
THEN DATEDIFF(hh, datetime_in, ship_date)
ELSE 0 END) > 120)
I am trying to optimize so the query 3 can be executed and give results in less then 5 minutes maybe?
Depending on how much data you're working with, utilising temporary tables and indices on those tables may be the most optimal approach. It's a technique I tend to use regularly when I work with databases with insufficient indices, or where correlated subqueries are expensive:
DROP TABLE IF EXISTS #ids;
SELECT Id_A
INTO #ids
FROM [Database]..[Table_A]
WHERE location = 'US'
AND datetime_in >= DATEADD(DAY,-30,GETDATE())
AND (
CASE WHEN date_sent IS NULL THEN DATEDIFF(hh, datetime_in, GETDATE())
WHEN date_sent IS NOT NULL THEN DATEDIFF(hh, datetime_in, ship_date)
ELSE 0 END
) > 120;
CREATE INDEX [IX_ids] ON #ids(Id_A);
SELECT *
FROM [Database]..[Table_B]
WHERE EXISTS (
SELECT * FROM #ids WHERE Id_A = Id_B
);
It looks like your are just trying to do a JOIN. Why not trying to make it simple, it will be MUCH faster that way:
SELECT TB.*
FROM [Database]..[Table_B] AS TB
JOIN [Database]..[Table_A] AS TA
ON TB.Id_B = TA.Id_A
WHERE TA.location = 'US'
AND TA.datetime_in >= DATEADD(DAY,-30,GETDATE())
AND (CASE WHEN TA.date_sent IS NULL THEN DATEDIFF(hh, TA.datetime_in, GETDATE())
WHEN TA.date_sent IS NOT NULL THEN DATEDIFF(hh, TA.datetime_in, TA.ship_date)
ELSE 0 END) > 120)

Combine rows on case when with non numeric

HI all i'm trying to get all rows rolled up to one. I have tried MAX Case when but there is a non numeric string in the case when and it isn't working to roll up the data. I have tried to find other examples but can't so i'm asking for your help. Thanks in advance
I have two fields that have different data but all have the same control number and i need to get all data for the control number rolled into one row.
SELECT CNTL_NUM
,TRANS_TYP
,CASE WHEN SEQ_NUM = '02' THEN SUBSTRING(TRANS_INFO,28,9) END AS 'SSN'
,CASE WHEN SEQ_NUM = '11' THEN SUBSTRING(TRANS_INFO,46,2) END AS 'IPS_STATE'
FROM LVJPROD.IPS_LNA
WHERE TRANS_TYP = 'TA'
GROUP BY CNTL_NUM, TRANS_TYP,SEQ_NUM,TRANS_INFO
order by CNTL_NUM
I am hoping to get all 6 lines rolled up to one from the screen shot below
You can group them again. The problem is with the case statement where it manipulates data. So you need to treat these as a subquery and have a grouping in the outer query and the MAX should work
WITH yourtable
AS (SELECT cntl_num,
trans_typ,
CASE
WHEN seq_num = '02' THEN Substring(trans_info, 28, 9)
END AS ssn,
CASE
WHEN seq_num = '11' THEN Substring(trans_info, 46, 2)
END AS ips_state
FROM lvjprod.ips_lna
WHERE trans_typ = 'TA'
GROUP BY cntl_num,
trans_typ,
seq_num,
trans_info)
SELECT cntl_num,
trans_typ,
Max(ssn),
Max(ips_state)
FROM yourtable
GROUP BY cntl_num,
trans_typ
ORDER BY cntl_num;
OR
SELECT cntl_num,
trans_typ,
Max(ssn),
Max(ips_state)
FROM (SELECT cntl_num,
trans_typ,
CASE
WHEN seq_num = '02' THEN Substring(trans_info, 28, 9)
END AS ssn,
CASE
WHEN seq_num = '11' THEN Substring(trans_info, 46, 2)
END AS ips_state
FROM lvjprod.ips_lna
WHERE trans_typ = 'TA'
GROUP BY cntl_num,
trans_typ,
seq_num,
trans_info) a
GROUP BY cntl_num,
trans_typ
ORDER BY cntl_num;

sql server select within select

say I have the following query:
select ID, ActualDate, DueDate
from table1
What I need to do is to add another field called Flag
which will be marked as "Y" if ActualDate is greater than DueDate
select ID, ActualDate, DueDate,
CASE
WHEN ActualDate > DueDate THEN 'Y'
ELSE 'N'
END as Flag
from table1
The above won't work as I get invalid column name ActualDate. Invalid column name DueDate.
What I need to do is a select within a select like this:
select ID, ActualDate, DueDate,
CASE
WHEN ActualDate > DueDate THEN 'Y'
ELSE 'N'
END as Flag
from
(select ID, ActualDate, DueDate
from table1) tbl1
)
If your table has the fields in it, then the following should work without the need for a subquery:
select ID,
ActualDate,
DueDate,
CASE
WHEN ActualDate > DueDate
THEN 'Y'
ELSE 'N'
END as Flag
FROM table1
You can use a subquery but it is unnecessary:
select ID,
ActualDate,
DueDate,
CASE
WHEN ActualDate > DueDate
THEN 'Y'
ELSE 'N'
END as Flag
FROM
(
select ID, ActualDate, DueDate
from table1
) tbl1

t-sql include column if condition exists

If I have an sql statement:
select call_id, title, description, due_date
from calls
I want to include a column if the condition due_date < getdate() is true.
I was thinking this column would be of type bit, and be set to 1 if condition is true and 0 if condition is false.
Know how I can do this?
select
call_id,
title,
description,
due_date,
case when due_date < getdate() then 1 else 0 end
from calls
SELECT call_id, title, description, due_date,
CASE WHEN due_date < getdate() THEN CAST(1 AS BIT) ELSE 0 END overdue
FROM calls