SQL Retrieve First Matching row - sql

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

Related

select rows in sql with latest date from 3 tables in each group

I'm creating PREDICATE system for my application.
Please see image that I already
I have a question how can I select rows in SQL with latest date "Taken On" column tables for each "QuizESId" columns, before that I am understand how to select it but it only using one table, I learn from this
select rows in sql with latest date for each ID repeated multiple times
Here is what I have already tried
SELECT tt.*
FROM myTable tt
INNER JOIN
(SELECT ID, MAX(Date) AS MaxDateTime
FROM myTable
GROUP BY ID) groupedtt ON tt.ID = groupedtt.ID
AND tt.Date = groupedtt.MaxDateTime
What I am confused about here is how can I select from 3 tables, I hope you can guide me, of course I need a solution with good query and efficient performance.
Thanks
This is for SQL Server (you didn't specify exactly what RDBMS you're using):
if you want to get the "latest row for each QuizId" - this sounds like you need a CTE (Common Table Expression) with a ROW_NUMBER() value - something like this (updated: you obviously want to "partition" not just by QuizId, but also by UserName):
WITH BaseData AS
(
SELECT
mAttempt.Id AS Id,
mAttempt.QuizModelId AS QuizId,
mAttempt.StartedAt AS StartsOn,
mUser.UserName,
mDetail.Score AS Score,
RowNum = ROW_NUMBER() OVER (PARTITION BY mAttempt.QuizModelId, mUser.UserName
ORDER BY mAttempt.TakenOn DESC)
FROM
UserQuizAttemptModels mAttempt
INNER JOIN
AspNetUsers mUser ON mAttempt.UserId = muser.Id
INNER JOIN
QuizAttemptDetailModels mDetail ON mDetail.UserQuizAttemptModelId = mAttempt.Id
)
SELECT *
FROM BaseData
WHERE QuizId = 10053
AND RowNum = 1
The BaseData CTE basically selects the data (as you did) - but it also adds a ROW_NUMBER() column. This will "partition" your data into groups of data - based on the QuizModelId - and it will number all the rows inside each data group, starting at 1, and ordered by the second condition - the ORDER BY clause. You said you want to order by "Taken On" date - but there's no such date visible in your query - so I just guessed it might be on the UserQuizAttemptModels table - change and adapt as needed.
Now you can select from that CTE with your original WHERE condition - and you specify, that you want only the first row for each data group (for each "QuizId") - the one with the most recent "Taken On" date value.

Data based on first row value in sql server

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')

Looking to convert a statement from using a single parameter to using a table

I am refactoring a stored procedure and I have the following issue:
I have this statement:
SELECT Top 1 unit_gid
FROM Some_Table
WHERE group_gid = #i_group_gid
ORDER BY effective_date desc
Now instead of supplying one group gid as a single parameter like in the above I wish to apply this statement to a collection of group gids which I have stored as a single column table.
So if I supply a list of 20 group gids I want to return a list 20 unit gids, the most recent one for each of those supplied group gids.
How can I do this without resorting to using loops? Is there a way that I can do it with CTEs for example?
You could join on the tables of gids, and use the row_number window function to get the most recent unit_gid per gid:
SELECT gid, unit_gid
FROM (SELECT s.gid AS gid,
unit_gid,
ROW_NUMBER() OVER (PARTITION BY gid ORDER BY effective_date DESC) rn
FROM some_table s
JOIN gids g ON s.gid = gids.gid) t
WHERE rn = 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

SQL Query to select top 2 for each value

I have a table with 3 columns, the data in column1 has repeating values and column 3 has totals, what I'd like to do is to return the top 2 totals for each value in column 1.
My query to create this table is below:
SELECT service,name, total
FROM [test].[dbo].[TestTable]
join test1.dbo.service
on substring(servan,0,4)=servicebn
where substring(servan,0,4)=servicebn and name <> testname
group by service,name,total
order by service,total desc
any help would be much appreciated
if you are using SQL Server 2005+, you can use Common Table Expression and Window Function.
WITH recordsList
AS
(
SELECT service, name, total,
DENSE_RANK() OVER (PARTITION BY service
ORDER BY total DESC) rn
FROM [test].[dbo].[TestTable]
INNER join test1.dbo.servd
on substring(servan,0,4)=servicebn
where substring(servan,0,4) = servicebn and
name <> testname
)
SELECT service, name, total
FROM recordsLIst
WHERE rn <= 2
As a side note, this query has poor in performance because it requires FULL TABLE SCAN on every table. The reason is because of the join condition substring(servan,0,4)=servicebn. It doesn't use index.