Data based on first row value in sql server - sql

I have a table Activity having data like below.It contains multiple rows of CreatedBY like IVR,Raghu and IT.
But I need to get the data only when the first row of CreatedBY='IVR'.

This following query will return firstcreated row for each user (CreatedBy)-
SELECT * FROM
(
SELECT *,
ROW_NUMBER() OVER(PARTITION BY CreatedBy ORDER BY CreatedBy,[Date And Time]) RN
FROM your_table
)A
WHERE RN = 1

I suspect you want the first row per ticket_no. At least, that makes more sense as a query.
If so, in SQL Server, you can use a correlated subquery:
select a.*
from activity a
where a.createdby = 'Raghu' and
a.datetime = (select min(a2.datetime)
from activity a2
where a2.ticket_no = a.ticket_no
);

use exists
select a.*
from table a where createdby='IVR'
and datetime in
(select min(datetime) from table b where a.ticketno=b.ticketno
and createdby='IVR')

Related

Listing multiple columns in a single row in SQL

(select ID,EXTERNAL_TRANSACTION_ID,EXTERNAL_TRANSACTION_TYPE,ROW_NUMBER() OVER(PARTITION BY EXTERNAL_TRANSACTION_ID ORDER BY ID ) AS SEQNUM
from AC_POS_TRANSACTION_TRK aptt WHERE [RESULT] ='Success'
GROUP BY ID, EXTERNAL_TRANSACTION_ID,EXTERNAL_TRANSACTION_TYPE )
Hello,
On above query, I want to get rows of transaction id's which has seqnum=1 and seqnum=2
But if that transaction id has no second row (seqnum=2), I dont want to get any row for that transaction id.
Thanks!!
Something like this
Not 100% sure if this is correct without you table definition, but my understanding is that you want to EXCLUDE records if that record has an entry with seqnum=2 -- you can't use a where clause alone because that would still return seqnum = 1.
You can use an exists /not exists or in/not in clause like this
(select ID,EXTERNAL_TRANSACTION_ID,EXTERNAL_TRANSACTION_TYPE,ROW_NUMBER() OVER(PARTITION BY EXTERNAL_TRANSACTION_ID ORDER BY ID ) AS SEQNUM
from AC_POS_TRANSACTION_TRK aptt WHERE [RESULT] ='Success'
and not exists ( select 1 from AC_POS_TRANSACTION_TRK a where a.id = aptt.id
and a.seqnum = 2)
GROUP BY ID, EXTERNAL_TRANSACTION_ID,EXTERNAL_TRANSACTION_TYPE )
basically what this does is it excludes records if a record exists as specified in the NOT EXISTS query.
One option you can try is to add a count of rows per group using the same partioning critera and then filter accordingly. Not entirely sure about your query without seeing it in context and with sample data - there's no aggregation so why use group by?
However can you try something along these lines
select * from (
select ID,EXTERNAL_TRANSACTION_ID,EXTERNAL_TRANSACTION_TYPE,
Row_Number() over(partition by EXTERNAL_TRANSACTION_ID order by ID) as SEQNUM,
Count(*) over(partition by EXTERNAL_TRANSACTION_ID) Qty
from AC_POS_TRANSACTION_TRK
where [RESULT] ='Success'
)x
where SEQNUM in (1,2) and Qty>1
This should do the job.
With Qry As (
-- Your original query goes here
),
Select Qry.*
From Qry
Where Exists (
Select *
From Qry Qry1
Where Qry1.EXTERNAL_TRANSACTION_ID = Qry.EXTERNAL_TRANSACTION_ID
And Qry1.SEQNUM = 1
)
And Exists (
Select *
From Qry Qry2
Where Qry2.EXTERNAL_TRANSACTION_ID = Qry.EXTERNAL_TRANSACTION_ID
And Qry2.SEQNUM = 2
)
BTW, your original query looks problematic to me, specifically I think that instead of a GROUP BY columns those columns should be in the PARTITION BY clause of the OVER statement, but without knowing more about the table structures and what you're trying to achieve, I could not say for sure.

Filter SQL data by repetition on a column

Very simple basic SQL question here.
I have this table:
Row Id __________Hour__Minute__City_Search
1___1409346767__23____24_____Balears (Illes)
2___1409346767__23____13_____Albacete
3___1409345729__23____7______Balears (Illes)
4___1409345729__23____3______Balears (Illes)
5___1409345729__22____56_____Balears (Illes)
What I want to get is only one distinct row by ID and select the last City_Search made by the same Id.
So, in this case, the result would be:
Row Id __________Hour__Minute__City_Search
1___1409346767__23____24_____Balears (Illes)
3___1409345729__23____7______Balears (Illes)
What's the easier way to do it?
Obviously I don't want to delete any data just query it.
Thanks for your time.
SELECT Row,
Id,
Hour,
Minute,
City_Search
FROM Table T
JOIN
(
SELECT MIN(Row) AS Row,
ID
FROM Table
GROUP BY ID
) AS M
ON M.Row = T.Row
AND M.ID = T.ID
Can you change hour/minute to a timestamp?
What you want in this case is to first select what uniquely identifies your row:
Select id, max(time) from [table] group by id
Then use that query to add the data to it.
SELECT id,city search, time
FROM (SELECT id, max(time) as lasttime FROM [table] GROUP BY id) as Tkey
INNER JOIN [table] as tdata
ON tkey.id = tdata.id AND tkey.lasttime = tdata.time
That should do it.
two options to do it without join...
use Row_Number function to find the last one
Select * FROM
(Select *,
row_number() over(Partition BY ID Order BY Hour desc Minute Desc) as RNB
from table)
Where RNB=1
Manipulate the string and using simple Max function
Select ID,Right(MAX(Concat(Hour,Minute,RPAD(Searc,20,''))),20)
From Table
Group by ID
avoiding Joins is usually much faster...
Hope this helps

SQL Retrieve First Matching row

I have a database which has two tables. A Call_Info table which holds details about incoming / outgoing calls and has a unique ID named Call_ID. I have a second table which is linked and called the After_Call_Work table.
Each call will have only one After Call Work Record. The dataset is a bit messed up and for the same call there are occasionaly 3 or 4 after call work records. How can I when doing queries just retrieve the earliest After Call Work Record for that particular call ignoring the rest? I imagined using SQL function First_Value but it doesn't seem to be the right one.
Using Microsoft SQL Server 2012.
Any ideas?
You should be able to use select top, something like this:
SELECT TOP 1
FROM call_info ci JOIN after_call_work acw ON ci.call_id=acw.call_id
ORDER BY acw.work_time DESC
WHERE ci.call_id=<your_call_id>
This can be achieved by taking advantage of Window Function
WITH call_List
AS
(
SELECT Call_ID, OtherColumns, DateColumn,
ROW_NUMBER() OVER (PARTITION BY Call_ID ORDER BY DateColumn ASC) rn
FROM After_Call_Work
)
SELECT a.*, b.OtherColumns, b.DateColumn
FROM Call_Info a
INNER JOIN call_List b
ON a.Call_ID = b.Call_ID
WHERE b.rn = 1
SQLFiddle Demo
TSQL Ranking Function
WITH g AS (SELECT ROW_NUMBER() OVER (PARTITION BY callid
ORDER BY date ASC) AS row,* from after_call_work
select * from call_info cinfo inner join g on
cinfo.callid = g.callid and g.row=1

T-SQL, how to do this group by query?

I have a view with this information:
TableA (IDTableA, IDTableB, IDTableC, Active, date, ...)
For each register in TableA and each register in tableC, I want the register of tableB that have the max date and is active.
select IDTableA, IDtableC, IDTableB, Date, Active
from myView
where Active = 1
group by IDTableA, IDTableC
Having Max(Date)
order by IDTableA;
This query works with SQLite, but if I try this query in SQL Server I get an error that say that IDTableB in the select is not contained in the group clause.
I know that in theory the first query in the SQLite shouldn't work, but do it.
How can I do this query in SQL Server?
Thanks.
According to SQL 92, if you use GROUP BY clause, then in SELECT output expression list you can only use columns mentioned in GROUP BY list, or any other columns but they must be wrapped in aggregate functions like count(), sum(), avg(), max(), min() and so on.
Some servers like MSSQL, Postgres are strict about this rule, but for example MySQL and SQLite are very relaxed and forgiving - and this is why it surprised you.
Long story short - if you want this to work in MSSQL, adhere to SQL92 requirement.
This query in SQLServer
select IDTableA, IDtableC, IDTableB, Date, Active
from myView v1
where Active = 1
AND EXISTS (
SELECT 1
FROM myView v2
group by v2.IDTableA, v2.IDTableC
Having Max(v2.Date) = v1.Date
)
order by v1.IDTableA;
OR
Also in SQLServer2005+ you can use CTE with ROW_NUMBER
;WITH cte AS
(
select IDTableA, IDtableC, IDTableB, [Date], Active,
ROW_NUMBER() OVER(PARTITION BY IDTableA, IDTableC ORDER BY [Date] DESC) AS rn
from myView v1
where Active = 1
)
SELECT *
FROM cte
WHERE rn = 1
ORDER BY IDTableA
Try this,
select * from table1 b
where active = 1
and date = (select max(date) from table1
where idtablea = b.idtablea
and idtablec = b.idtablec
and active = 1);
SQLFIDDLE DEMO

Row with the highest ID

You have three fields ID, Date and Total. Your table contains multiple rows for the same day which is valid data however for reporting purpose you need to show only one row per day. The row with the highest ID per day should be returned the rest should be hidden from users (not returned).
To better picture the question below is sample data and sample output:
ID, Date, Total
1, 2011-12-22, 50
2, 2011-12-22, 150
The correct result is:
2, 2012-12-22, 150
The correct output is single row for 2011-12-22 date and this row was chosen because it has the highest ID (2>1)
Assuming that you have a database that supports window functions, and that the date column is indeed just date (and not datetime), then something like:
SELECT
* --TODO - Pick columns
FROM
(
SELECT ID,[Date],Total,ROW_NUMBER() OVER (PARTITION BY [Date] ORDER BY ID desc) rn
FROM [Table]
) t
WHERE
rn = 1
Should produce one row per day - and the selected row for any given day is that with the highest ID value.
SELECT *
FROM table
WHERE ID IN ( SELECT MAX(ID)
FROM table
GROUP BY Date )
This will work.
SELECT *
FROM tableName a
INNER JOIN
(
SELECT `DATE`, MAX(ID) maxID
FROM tableName
GROUP BY `DATE`
) b ON a.id = b.MaxID AND
a.`date` = b.`date`
SQLFiddle Demo
Probably
SELECT * FROM your_table ORDER BY ID DESC LIMIT 1
Select MAX(ID),Data,Total from foo
for MySQL
Another simple way is
SELECT TOP 1 * FROM YourTable ORDER BY ID DESC
And, I think this is the most simple way!
SELECT * FROM TABLE_SUM S WHERE S.ID =
(
SELECT MAX(ID) FROM TABLE_SUM
WHERE CDATE = GG.CDATE
GROUP BY CDATE
)