How to use distinct when you select multiple column in SQL - sql

I have use simple inner join statement and getting result into CTE table. I want to select distinct 'ServiceId' from CTE. I have following query
SELECT DISTINCT(ServicesId), ServiceNo, ServiceDate, DealerCode FROM CTE_Temp
Suppose there are duplicate entries of ServiceId in CTE then I want to select first entry only and ignore rest of them.

You can use ROW_NUMBER() OVER() for this. Just replace the column in the ORDER BY to define what's first.
;WITH AnotherCTE AS(
SELECT
ServicesId, ServiceNo, ServiceDate, DealerCode,
RN = ROW_NUMBER() OVER(PARTITION BY ServicesID ORDER BY ServiceDate DESC)
FROM CTE_Temp
)
SELECT
ServicesId, ServiceNo, ServiceDate, DealerCode
FROM AnotherCTE
WHERE RN = 1

Related

Perform pivot operation on the table but facing problem as it requires multiple aggregate function to segregate dates into two columns

I have this table named hotel which contains EmpId and their corresponding [check-in/out] column in datetime format.
Now, I want the data in table to look like this.
I have tried following simple query and it's working correctly:
select EmpId, min([Check-in/out]) as Checkin, max([Check-in/out]) as Checkout
from [dbo].[hotel]
group by EmpId;
But i want to do it using pivot operator in sql server. I have tried the following query but it's incorrect:
select EmpId, Min([Check-in/out]) AS Checkin, Max([Check-in/out]) AS Checkout
FROM
(select EmpId, [Check-in/out] from [dbo].[hotel]) AS SourceTable
PIVOT
(
min([Check-in/out])
FOR [Check-in/out] IN(Checkin)
)AS PivotTable1
PIVOT
(
max([Check-in/out])
FOR [Check-in/out] IN(Checkout)
)AS PivotTable2;
Here again my comment as answer with an example:
I suggest using cte / subqueries in order to approach this problem... first of all, select EmpID, time and rownumber (partition by empid and order by time) - this gives you all checkins with odd rownumber and all checkouts with even rownumber. Next - basing on this query - select empid, time and CASE WHEN rownumber%2=0 THEN 'CHECKOUT' ELSE 'CHECKIN' END AS CheckInOut... this result again can be used in your pivot statement
Example:
WITH cte AS(
SELECT *, ROW_NUMBER() OVER (PARTITION BY EmpID ORDER BY CheckInOut) rn
FROM T1
),
cteInOut AS(
SELECT EmpID, CheckInOut, CASE WHEN rn%2 = 0 THEN N'CheckOut' ELSE N'CheckIn' END AS CheckInOutState
FROM cte
),
cteInOuntSrt AS(
SELECT EmpID, CheckInOut, CheckInOutState, ROW_NUMBER() OVER (PARTITION BY EmpID, CheckInOutState ORDER BY CheckInOut) rn1
FROM cteInOut
)
select EmpID, rn1 AS CheckIndIdx, CheckIn, CheckOut
from cteInOuntSrt
pivot
(
min(CheckInOut)
for CheckInOutState in ([CheckIn], [CheckOut])
) piv
ORDER BY 1, 2;
fiddle: http://sqlfiddle.com/#!18/af6f3/1/1
If the values line up, you can use lead() and row_number():
select c.empid, checkin, checkout
from (select c.*, [Check-in/out] as checkin,
lead([Check-in/out]) over (partition by empid order by [Check-in/out]) as checkout,
row_number() over (partition by empid order by [Check-in/out]) as seqnum
from [Check-in/out] c
) c
where seqnum % 2 = 1;
This does the following calculations:
Calculate the next date/time value.
Enumerate the rows, starting the count from 1.
Taking the odd-numbered rows. These are the check ins.

query without duplicates SQL

I have query with duplicates. And now I need to build query without duplicates. I'm trying to do it, but my query need long time. My query with duplicates:
SELECT
c.*
FROM
Clients c
INNER JOIN
(
SELECT
iin,
COUNT(iin) AS countIIN
FROM
Clients
GROUP BY
iin
HAVING
COUNT(iin) > 1
) cc
ON c.IIN = cc.IIN
ORDER BY
c.last_name DESC
I need above anti-query.
You can use below query to find only unique record.
WITH CTE AS
(SELECT *, COUNT(IIN) OVER (PARTITION BY IIN) RECORDCOUNT FROM CLIENTS)
SELECT * FROM CTE WHERE RECORDCOUNT =1
make sure * should be replace in query with required column.
Also if you want to fetch unique record from duplicate list as well then you can choose below query
WITH CTE AS
(SELECT *, RECORD_NUMBER() OVER (PARTITION BY IIN ORDER BY IIN) RECORDCOUNT FROM CLIENTS)
SELECT * FROM CTE WHERE RECORDCOUNT =1
To find duplicates in SQL Row_Number() function is best option,
Please check following query
WITH [CTE NoDuplicates] AS
(
SELECT
RN = ROW_NUMBER() OVER (PARTITION BY iin ORDER BY c.last_name DESC),
*
FROM Clients
)
DELETE FROM [CTE DUPLICATE] WHERE RN = 1

How to select distinct records based on condition

I have table of duplicate records like
Now I want only one record from duplicate records which has latest created date as How can I do it ?
use row_number():
select EnquiryId, Name, . . .
from (select t.*,
row_number() over (partition by enquiryID order by CreatedDate desc) as seqnum
from table t
) t
where seqnum = 1;
Use ROW_NUMBER function to tag the duplicate records ordered by CreatedDate, like this:
;with CTE AS (
select *, row_NUMBER() over(
partition by EnquiryID -- add columns on which you want to identify duplicates
ORDER BY CreatedDate DESC) as rn
FROM TABLE
)
select * from CTE
where rn = 1

How to get the row that holds the last value in a queue of identical values? (SQL)

I think it's easier to show you an image:
So, for each fld_call_id, go to the next value, if it's identical. When we get to the last value, I need the value in column fld_menu_id.
Or, to put it in another way, eliminate fld_call_id duplicates and save only the last one.
You can use ROW_NUMBER:
WITH CTE AS(
SELECT RN = ROW_NUMBER() OVER (PARTITION BY fld_call_id ORDER BY fld_id DESC),
fld_menu_id
FROM dbo.TableName
)
SELECT fld_menu_id FROM CTE WHERE RN = 1
You can create a Rank column and only select that row, something along the lines of the following:
;WITH cte AS
(
SELECT
*
,RANK() OVER (PARTITION BY fld_call_id ORDER BY fld_id DESC) Rnk
FROM YourTable
)
SELECT
*
FROM cte
WHERE Rnk=1
So you GROUP BY fld_call_id and ORDER BY fld_id in descending order so that the last value comes first. These are the rows where Rnk=1.
Edit after comments of OP.
SELECT Table.*
FROM Table
INNER JOIN
(
SELECT MAX(fldMenuID) AS fldMenuID,
fldCallID
FROM Table
GROUP BY fldCallID
) maxValues
ON (maxValues.fldMenuID = Table.fldMenuID
AND maxValues.fldCallID= Table.fldCallID)
Hope This works
SELECT A.*
FROM table A
JOIN (SELECT fld_id,
ROW_NUMBER() OVER (PARTITION BY Fld_call_id ORDER BY fld_id DESC) [Row]
FROM table) LU ON A.fld_id = LU.fld_id
WHERE LU.[Row] = 1

Select the first instance of a record

I have a table, myTable that has two fields in it ID and patientID. The same patientID can be in the table more than once with a different ID. How can I make sure that I get only ONE instance of every patientID.?
EDIT: I know this isn't perfect design, but I need to get some info out of the database and today and then fix it later.
You could use a CTE with ROW_NUMBER function:
WITH CTE AS(
SELECT myTable.*
, RN = ROW_NUMBER()OVER(PARTITION BY patientID ORDER BY ID)
FROM myTable
)
SELECT * FROM CTE
WHERE RN = 1
It sounds like you're looking for DISTINCT:
SELECT DISTINCT patientID FROM myTable
you can get the same "effect" with GROUP BY:
SELECT patientID FROM myTable GROUP BY patientID
The simple way would be to add LIMIT 1 to the end of your query. This will ensure only a single row is returned in the result set.
WITH CTE AS
(
SELECT tableName.*,ROW_NUMBER() OVER(PARTITION BY patientID ORDER BY patientID) As 'Position' FROM tableName
)
SELECT * FROM CTE
WHERE
Position = 1