i am working on sql query please please check and give me the solution
please find the bellow task brief detail of tables
table 1 'tbl_SuperAdmin' having on filed
data like example
s_id name age gtc.......
1 abc 23 .........
2 cda 42 ..........
another table 2 having 'tbl_Renewal'
renewalid renname date supid Payed etc......
1 first - 1 1 ........
2 first - 2 1 ........
3 second - 1 0 ........
4 second - 1 1 ........
5 third- 1 1 ........
query is select *from tbl_superadmin as a inner join tbl_Renewal as b on a.s_id=b.supid
Result is
s_id name age gtc....... renewalid renname date supid Payed etc.......
1 abc 23 .............1 first - 1 1 ........
2 cda 42 .............2 first - 2 1 ........
1 abc 23 .............3 second - 1 0 ........
1 abc 23 .............4 second - 1 1 ........
1 abc 23 .............5 third - 1 1 ........
here i want how has payed=1 and renewalid desc and no need for s_id not repeat of 1 more the one time
i want to show my result like
s_id name age gtc....... renewalid renname date supid Payed etc.......
1 abc 23 .............5 third - 1 1 ........
2 cda 42 .............2 first - 2 1 ........
like this result i want please any body help it
thanks
pradeep
To remove the duplicates you need to use Windows Function.
With cte as
(
select *,row_number() over(partition by s_id order by renewalid desc )rn
from tbl_superadmin as a
inner join tbl_Renewal as b
on a.s_id=b.supid
)
Select * from cte where rn=1
Demo in SQL FIDDLE
Update
;With cte as
(
select *,row_number() over(partition by s_id order by renewalid desc )rn
from alz_SuperAdmin as a inner join alz_Renewal as b on a.s_id=b.supid
)
select top 2 CONVERT(varchar(6),a.lastdate,6) as lastdate,
(select name from alz_states where ID=a.joblocation ) as locat,
from alz_jobpost as a
inner join
(Select col1,col2,col3.... from cte where rn=1 )ct
on ct.commonColumn=a.CommonColumn and
ct.Product in
(Select query)
You should use a GROUP BY and ORDER in your query. Something like this:
SELECT
*
FROM
tbl_SuperAdmin AS a
INNER JOIN
tbl_Renewal AS b
ON
a.s_id = b.supid
GROUP BY
a.s_id
ORDER BY
b.renewalid
DESC
Related
I have a data set produced from a UNION query that aggregates data from 2 sources.
I want to select that data based on whether or not data was found in only of those sources,or both.
The data relevant parts of the set looks like this, there are a number of other columns:
row
preference
group
position
1
1
111
1
2
1
111
2
3
1
111
3
4
1
135
1
5
1
135
2
6
1
135
3
7
2
111
1
8
2
135
1
The [preference] column combined with the [group] column is what I'm trying to filter on, I want to return all the rows that have the same [preference] as the MIN([preference]) for each [group]
The desired output given the data above would be rows 1 -> 6
The [preference] column indicates the original source of the data in the UNION query so a legitimate data set could look like:
row
preference
group
position
1
1
111
1
2
1
111
2
3
1
111
3
4
2
111
1
5
2
135
1
In which case the desired output would be rows 1,2,3, & 5
What I can't work out is how to do (not real code):
SELECT * WHERE [preference] = MIN([preference]) PARTITION BY [group]
One way to do this is using RANK:
SELECT row
, preference
, [group]
, position
FROM (
SELECT row
, preference
, [group]
, position
, RANK() OVER (PARTITION BY [group] ORDER BY preference) AS seq
FROM t) t2
WHERE seq = 1
Demo here
Should by doable via simple inner join:
SELECT t1.*
FROM t AS t1
INNER JOIN (SELECT [group], MIN(preference) AS preference
FROM t
GROUP BY [group]
) t2 ON t1.[group] = t2.[group]
AND t1.preference = t2.preference
This is my first question (and sorry for my English)
I have this table in SQL Server:
id_patient | date | id_drug
----------------------------------------------------
1 20200101 A
1 20200102 A
1 20200103 A
1 20200104 A
1 20200105 A
1 20200110 A
2 20200101 A
2 20200105 B
2 20200106 C
2 20200107 D
2 20200108 E
2 20200110 L
3 20200101 A
3 20200102 A
3 20200103 A
3 20200104 A
3 20200105 C
3 20200106 C
4 20200105 A
4 20200106 D
4 20200107 D
5 20200105 A
5 20200106 A
5 20200107 C
5 20200108 D
I would like to extract patient and drug for all patients who have taken at least 3 different drugs in a given period
I have tried:
select id_patient, count(distinct ID_drug)
from table
where date between XXX and YYY
group by id_patient
having count(Distinct ID_drug) > 3
but in this way -YES- I get all patients with 3 or more different id_drug in this date range but I can't get the ID_drug because in the count()
For example, I'd like to obtain:
Who help me ?
Thanks
You can use string_agg() in the most recent versions of SQL Server:
select id_patient, count(distinct ID_drug),
string_agg(id_drug, ',')
from table
where date between XXX and YYY
group by id_patient
having count(Distinct ID_drug) > 3;
If you want the original rows, you can use window functions. Unfortunately, SQL Server does not support count(distinct) as a window function, but there is an easy work-around using dense_rank():
select t.*
from (select t.*,
(dense_rank() over (partition by id_patient order by id_drug) +
dense_rank() over (partition by id_patient order by id_drug desc)
) as num_drugs
from t
where . . .
) t
where num_drugs >= 3;
SELECT id_patient,
ID_drug
FROM table
WHERE id_patient IN (
SELECT id_patient
FROM table
WHERE date
BETWEEN XXX
AND YYY
GROUP BY id_patient
HAVING COUNT(DISTINCT ID_drug) >= 3
)
GROUP BY id_patient,
ID_drug;
I have three tables:
Table 1 : Emplyee Details
E_Id Name Department
1 A Manager
2 B Manager
3 C Manager
4 D Engineer
5 E Engineer
6 F Engineer
Table 2 : Salary Details
Sl_Id Name Amount
1 Bsaic_Mng 30000
2 Basic_ENG 20000
Table 3 : Employee Salary
ES_Id E_Id Sl_Id
1 1 1
2 2 1
3 4 2
4 5 2
Here in Table3 field E_ID is a reference to Table1.E_Id
and SL_ID is a reference to Table2.SL_id.
So I wanto Result Which Employee Has Not Salary Define Like E_Id 3 AND 6
You can achieve it as below:
Employee whose salary is not defined in EmployeeSalary table
SELECT *
FROM Emplyee
WHERE E_Id NOT IN (
SELECT E_Id
FROM EmployeeSalary
)
JOIN is not required here
You can do it using a LEFT JOIN like following.
SELECT ED.* FROM
[Emplyee Details] ED
LEFT JOIN [Employee Salary] ES ON ES.E_ID=ED.E_Id
WHERE ES.E_ID IS NULL
I feel NOT EXISTS should be a better option to achieve this for this case.
SELECT * FROM
[Emplyee Details] ED
WHERE NOT EXISTS
(
SELECT 1 FROM [Employee Salary] ES WHERE ES.E_ID=ED.E_Id
)
SELECT
AgentID,Seat1,SeatUpdated_1,Seat2,SeatUpdated_2,
Seat3,SeatUpdated_3,nTimesSeatChanged,
DATEDIFF(MS,(F.SeatUpdated_1),(F.SeatUpdated_3)) AvgTime
FROM ##final F
Now I have to pick SeatUpdated_3 in the diff function based on column nTimesSeatChanges.
If it have value 2 for any agent, the selected column should be SeatUpdated_2
From the limited information would look at how you store the information first of all. It looks like you are storing related values across column. It would be simpler to work with if you looked at storing them as rows.
Current:
AgentID Seat1 SeatUpdated_1 Seat2 SeatUpdated_2 Seat3 SeatUpdated_3 nTimesSeatChanged
------- ----- ------------- ----- ------------- ----- ------------- -----------------
1 11 21 01/02/2015 31 01/03/2015 2
TO :
TableKey AgentID Seat SeatUpdated
-------- ------- ---- -----------
1 1 11 01/01/2015
2 1 12 01/02/2015
3 1 13 01/03/2015
4 2 22 02/02/2015
5 2 23 02/03/2015
Then work in simple queries to get the end result. I'm not an expert by any means but this is how I would approach it.
;
--Some sample data
WITH CTE_DATA as
(
SELECT '1' as TableKey, '1' as 'AgentID','11' as'Seat','01/01/2015' as 'SeatUpdated'
UNION
SELECT '2','1','12','01/02/2015'
UNION
SELECT '3','1','13','01/03/2015'
UNION
SELECT '4','2','22','02/02/2015'
UNION
SELECT '5','2','23','02/03/2015'
)
,
--Get Min Seat
CTE_Min AS (
SELECT AgentID
,MIN(Seat) AS min_seat
FROM CTE_DATA
GROUP BY AgentID
)
--Get max seat
,CTE_Max AS (
SELECT AgentID
,MAX(Seat) AS max_seat
FROM CTE_DATA
GROUP BY AgentID
)
--Stick them together
,CTE_Join AS (
SELECT Min.AgentID
,Min.min_seat
,max.max_seat
FROM CTE_Min min
JOIN CTE_Max max ON min.AgentID = max.AgentID
)
--Get the date
,CTE_JoinDate AS (
SELECT j.*
,d1.SeatUpdated AS min_date
,d2.SeatUpdated AS max_date
FROM CTE_Join j
LEFT JOIN CTE_DATA d1 ON j.AgentID = d1.AgentID
AND j.min_seat = d1.Seat
LEFT JOIN CTE_DATA d2 ON j.AgentID = d2.AgentID
AND j.max_seat = d2.Seat
)
--Work out nSeats
,CTE_nSeats AS (
SELECT AgentID
,COUNT(1) AS nSeats
FROM CTE_DATA
GROUP BY AgentID
)
--Final result set
SELECT j.*
,DATEDIFF(DAY, min_date, max_date) AS DIFF_Days
,n.nSeats
FROM CTE_JoinDate j
LEFT JOIN CTE_nSeats n ON j.AgentID = n.AgentID
I have a table like this
ProjectID PhaseID Comment CommentDate
1 1 a 2/15/2014
1 1 b 5/1/2014
1 2 c 8/15/2014
1 2 d 1/1/2015
2 1 e 1/21/2014
2 2 f 5/15/2014
2 2 g 1/1/2015
How do I get the lastest (Top 1) comment for each project for each phase? For example, for Project 1, phase 1, I should get "b" and "5/1/2014"
Thank you!
select ProjectID,PhaseID,Comment,CommentDate from
(select row_number() over(partition by Project_ID,PhaseID order by CommentDate desc) as rn,* from table) a
where a.rn = 1
This type of query works best when there's an identity column (and values are always inserted in order) but this should get you what you need assuming there's no overlapping commentDates
select t.*
from table t
inner join (
SELECT max(commentDate) as maxDate,
phaseId,
projectId
FROM table
group by phaseId, projectId
) maxComments on t.phaseId = maxComments.phaseId
and t.projectId = maxComments.projectId
and t.commentDate = maxComments.maxDate