SQL Select only unique values in column - sql

I have the below query that is pulling from a table where a record (Employee ID) can have more than 1 row of data. Because of this I have some rows with the highest (Max) EXAM_DATE. I have added in the MAX function into the SELECT Statement, however I am still retrieving rows with 2 or more dates per empl. This must be something simply that I am overlooking. Any help is appreciated.
SQL Query:
SELECT A.EMPLID, A.BUSINESS_TITLE, A.DEPTID, A.LOCATION, A.LAST_NAME,
A.FIRST_NAME, A.MIDDLE_NAME,
MAX(CONVERT(CHAR(10),D.EXAM_DT,121))AS EXAM_DATE, D.EXAM_TYPE_CD,
(CONVERT(CHAR(10),D.GH_EXPIRE_DATE,121)) AS EXPIRE_DATE, AA.NAME AS
Manager_Name
FROM ((PS_EMPLOYEES A INNER JOIN PS_EMPLMT_SRCH_QRY A1 ON (A.EMPLID =
A1.EMPLID AND A.EMPL_RCD = A1.EMPL_RCD AND A1.OPRID = 'HD065' ))
LEFT OUTER JOIN PS_GHS_HS_PPDSCRN D ON A.EMPLID = D.EMPLID)
--LEFT OUTER JOIN PS_GHS_REPORTS_TO H ON A.EMPLID = H.EMPLID
LEFT OUTER JOIN PS_EMPLOYEES AA ON AA.POSITION_NBR = A.REPORTS_TO
AND (( AA.EFFDT =
(SELECT MAX(A_ED.EFFDT) FROM PS_EMPLOYEES A_ED
WHERE AA.POSITION_NBR = A_ED.POSITION_NBR
AND A_ED.EFFDT <= SUBSTRING(CONVERT(CHAR,GETDATE(),121), 1, 10)) ))
WHERE ( ( A.EFFDT =
(SELECT MAX(A_ED.EFFDT) FROM PS_EMPLOYEES A_ED
WHERE A.EMPLID = A_ED.EMPLID
AND A.EMPL_RCD = A_ED.EMPL_RCD
AND A_ED.EFFDT <= SUBSTRING(CONVERT(CHAR,GETDATE(),121), 1, 10))
AND A.EFFSEQ =
(SELECT MAX(A_ES.EFFSEQ) FROM PS_EMPLOYEES A_ES
WHERE A.EMPLID = A_ES.EMPLID
AND A.EMPL_RCD = A_ES.EMPL_RCD
AND A.EFFDT = A_ES.EFFDT)
AND D.EXAM_TYPE_CD = 'PPD'))
AND A.EMPL_STATUS = 'A'
--AND NOT EXISTS (SELECT D.EMPLID, COUNT(*) AS 'TotalOccur' FROM PS_GHS_HS_PPDSCRN D GROUP BY D.EMPLID HAVING COUNT(*) > 1)
GROUP BY A.EMPLID, A.BUSINESS_TITLE, A.DEPTID, A.LOCATION, A.LAST_NAME,
A.FIRST_NAME, A.MIDDLE_NAME, D.EXAM_TYPE_CD, D.GH_EXPIRE_DATE, AA.NAME
ORDER BY 5
I tried running it with the Commented out code for NOT EXISTS, however when I run this I do not retrieve any results.
Sample Output:

The MAX in your WHERE should be fine.
Your EXPIRE_DATE is also different between the two records, and as the EXPIRE_DATE is included in the GROUP BY, it will cause the "duplicate".

Related

Pull a separate column that matches the (min) of an aggregate function

It works well so far but I am stumped from here as I am brand new to this. This query finds the closest distance match, pairing up every item in the "FAILED" folder against everything that isn't in the "FAILED" folder.
There is a column "RouteID" in the "table p" that I want to match up with the min() aggregate.
I cannot process how to make the SELECT query simply show the associated "RouteID" column from tbl p but ultimately, I want to turn this into an update query that will SET a.Route = p.Route that is associated with the min()
Any help would be appreciated.
SELECT a.name, a.Reference1,
MIN(round(ACOS(COS(RADIANS(90-a.lat))
*COS(RADIANS(90-p.latpoint))
+SIN(RADIANS(90-a.lat))
*SIN(RADIANS(90-p.latpoint))
*COS(RADIANS(a.lon-p.longpoint)))
*3958.756,2)) AS 'DISTANCE'
FROM tblOrder AS a WITH (NOLOCK)
LEFT JOIN
(
SELECT b.lat AS latpoint, b.lon AS longpoint,
b.Sequence, b.routeid
from tblOrder b WITH (NOLOCK)
WHERE b.CUSTID = 180016
AND b.routeID <> 'FAILED'
AND b.StopType = 1
) AS p ON 1=1
WHERE a.CustID = 180016
AND a.RouteID = 'FAILED'
AND a.StopType = 1
AND P.RouteID <> 'FAILED'
GROUP BY
a.name, a.Reference1
You can select them separately and then join them
SELECT c.name, c.Reference1, q.RouteID
FROM
(
SELECT a.name, a.Reference1,
MIN(round(ACOS(COS(RADIANS(90-a.lat))
*COS(RADIANS(90-p.latpoint))
+SIN(RADIANS(90-a.lat))
*SIN(RADIANS(90-p.latpoint))
*COS(RADIANS(a.lon-p.longpoint)))
*3958.756,2)) AS 'DISTANCE'
FROM tblOrder AS a WITH (NOLOCK)
LEFT JOIN
(
SELECT b.lat AS latpoint, b.lon AS longpoint,
b.Sequence, b.routeid
from tblOrder b WITH (NOLOCK)
WHERE b.CUSTID = 180016
AND b.routeID <> 'FAILED'
AND b.StopType = 1
) AS p ON 1=1
WHERE a.CustID = 180016
AND a.RouteID = 'FAILED'
AND a.StopType = 1
AND P.RouteID <> 'FAILED'
GROUP BY
a.name, a.Reference1
) c
LEFT JOIN
(
SELECT b.lat AS latpoint, b.lon AS longpoint,
b.Sequence, b.routeid
from tblOrderRouteStops b WITH (NOLOCK)
WHERE b.CUSTID = 180016
AND b.routeID <> 'FAILED'
AND b.StopType = 1
) AS q
ON q.routeID = c.DISTANCE

Unsupported subquery with table in join predicate

I am tried to run the next query but the next message appearance "Unsupported subquery with table in join predicate." Do you have some idea? I appreciate your comments.
WITH
D1 AS (
SELECT
SETID,
CUST_ID,
MAX(EFFDT) AS EFFDT
FROM
`g4s-data-reporting.g4s_data.PS_CUST_CREDIT`
WHERE
EFFDT <= CURRENT_TIMESTAMP()
GROUP BY
1,
2 ),
LEFT OUTER JOIN
`g4s-data-reporting.g4s_data.PS_CUST_CREDIT` D
ON
A.SETID = D.SETID
AND A.CUST_ID = D.CUST_ID
AND D.EFFDT = (
SELECT
MAX(EFFDT) --select 2
FROM
`g4s-data-reporting.g4s_data.PS_CUST_CREDIT` D1
WHERE
D1.SETID = D.SETID
AND D1.CUST_ID = D.CUST_ID
AND D1.EFFDT <= CURRENT_TIMESTAMP() )
WHERE
B.BUSINESS_UNIT IN ('00001',
'00048')
AND B.ITEM_STATUS = 'O'
AND B.ENTRY_TYPE NOT IN ('AO',
'CNVBC',
'MC',
'OA')

Display only 1 row in unioned query where they have rows certain criteria in another table

I couldn't think of a better title to this thread but I have the below Unioned query that is pulling in exam information per UserID that is unioned to pull in the total of the counts.
The problem is that when the UserID has two rows in PS_JOB AND one row has a PER_ORG value of 'CWR' and the other row has a PER_ORG value of 'EMP' then the query is returning 2 rows for this same UserID. In this scenario I only want to display the 'EMP' record, so that only 1 instance of their ID (that falls into this scenario) will count in my Totals (ZTOTAL).
I imagine I need some sort of WHERE condition with NOT EXISTS where it finds two rows with the same UserID, AND one row contains PER_ORG = 'EMP' and the other row contains PER_ORG = 'CWR', but am struggling as to how to code this. I don't want to exclude USERID's that have two rows in PS_JOB with any other combination of values for PER_ORG, other than 'EMP' and 'CWR'.
Current SQL:
SELECT
A.USERID,
A.IMMUN_CODE,
B.COMPANY,
COUNT(*) AS 'COUNT_OF_EXAMS'
FROM
PS_HS_IMMUN A,
PS_JOB B,
PS_EMPLMT_SRCH_QRY B1
WHERE
(B.USERID = B1.USERID
AND B.EMPL_RCD = B1.EMPL_RCD
AND B1.OPRID = 'GG125'
AND ( A.USERID = B.USERID
AND B.EFFDT = (SELECT MAX(B_ED.EFFDT)
FROM PS_JOB B_ED
WHERE B.USERID = B_ED.USERID
AND B.EMPL_RCD = B_ED.EMPL_RCD
AND B_ED.EFFDT <= SUBSTRING(CONVERT(CHAR,GETDATE(),121), 1, 10))
AND B.EFFSEQ = (SELECT MAX(B_ES.EFFSEQ)
FROM PS_JOB B_ES
WHERE B.USERID = B_ES.USERID
AND B.EMPL_RCD = B_ES.EMPL_RCD
AND B.EFFDT = B_ES.EFFDT)
)
)
AND A.HISTORY_ONLY <> 'Y'
GROUP BY A.USERID, A.IMMUN_CODE, B.COMPANY
UNION
SELECT
'ZTOTAL',
'',
'',
COUNT ( D.USERID)
FROM
(PS_HS_IMMUN D
LEFT OUTER JOIN
(PS_JOB E
INNER JOIN PS_EMPLMT_SRCH_QRY E1 ON
(E.USERID = E1.USERID
AND E.EMPL_RCD = E1.EMPL_RCD
AND E1.OPRID = 'GG125' )) ON
D.USERID = E.USERID)
WHERE
(
(E.EFFDT = (SELECT MAX(E_ED.EFFDT)
FROM PS_JOB E_ED
WHERE E.USERID = E_ED.USERID
AND E.EMPL_RCD = E_ED.EMPL_RCD
AND E_ED.EFFDT <= SUBSTRING(CONVERT(CHAR,GETDATE(),121), 1, 10))
AND E.EFFSEQ = (SELECT MAX(E_ES.EFFSEQ)
FROM PS_JOB E_ES
WHERE E.USERID = E_ES.USERID
AND E.EMPL_RCD = E_ES.EMPL_RCD
AND E.EFFDT = E_ES.EFFDT)
--AND D.EXAM_DT BETWEEN :1 AND :2
--AND E.COMPANY = :3
AND D.HISTORY_ONLY <> 'Y' )
)
Current Results From Above Query:
In this example, the two rows for UserID 4992 is duplicated because the UserID has two rows in the PS_JOBS table, hence why the USERID displays twice (and ultimately counts twice in the totals) in the query.
If I do a query from PS_JOBS for this USERID, you will see the two rows for this USERID AND the PER_ORG status of 'EMP' and 'CWR', respectfully.
SELECT *
FROM PS_JOB
WHERE EMPLID = '4992'
Results from above query:
I'm looking to avoid using Common Table Expressions as a solution. Thanks for any suggestions!

How to retrive the effective dated empid from PS_JOB table

I am new to peoplesoft. I can understand the effective date at a conceptual level, but I am still struggling with it in SQR. How do I retrieve the effective dated empid from PS_JOB table? How do I retrieve the valid empname from ps_names for the retrieved empid? Thanks in advance!
the current name - from the ps_names_vw view
you can use a similar where clause for the ps_job table.
select a.emplid,
a.name_type,
a.effdt,
a.last_name,
a.first_name,
a.middle_name,
a.name_prefix,
a.name_suffix,
a.last_name_srch,
a.first_name_srch,
a.name_display
from ps_names a
where a.effdt = (select max (b.effdt)
from ps_names b
where b.emplid = a.emplid and
b.name_type = a.name_type and
b.effdt <= to_date (to_char (sysdate, 'YYYY-MM-DD'), 'YYYY-MM-DD'));
Join names and job table with their respective effective date. here i have taken A, L, P, S employees assuming you need active employees' names only. if not , you can remove empl_status criterion. Also you need to specify the name_type in the main criterion , otherwise multiple rows may be returned for one emplid.
SELECT * FROM PS_NAMES N, PS_JOB J
WHERE N.EMPLID = J.EMPLID
AND N.EFFDT = (SELECT MAX(N1.EFFDT) FROM PS_NAMES N1
WHERE N1.EMPLID= N.EMPLID
AND N1.NAME_TYPE = N.NAME_TYPE
AND N1.EFFDT <= SYSDATE)
AND J.EFFDT = (SELECT MAX(J1.EFFDT) FROM PS_JOB J1
WHERE J1.EMPLID = J.EMPLID
AND J1.EMPL_RCD = J.EMPL_RCD
AND J1.EFFDT <= SYSDATE)
AND J.EFFSEQ = (SELECT MAX(J2.EFFSEQ) FROM PS_JOB J2
WHERE J2.EMPLID = J.EMPLID
AND J2.EMPL_RCD = J.EMPL_RCD
AND J2.EFFDT = J.EFFDT)
AND J.EMPL_STATUS IN ('A','L','P','S')
The below query will fetch you the most recent data of an employee with Emplid 'XXX' from PS_JOB
SELECT * FROM PS_JOB J
WHERE J.EMPLID = 'XXX'
AND J.EFFDT = (SELECT MAX(J1.EFFDT)
FROM PS_JOB J1
WHERE J1.EMPLID =J.EMPLID
AND J1.EMPL_RCD = J.EMPL_RCD
AND J1.EFFDT < TRUNC(SYSDATE))
AND J.EMPL_RCD = ( SELECT MAX(J2.EMPL_RCD)
FROM PS_JOB J2
WHERE J2.EMPLID = J.EMPLID
AND J2.EFFDT = J.EFFDT )
AND J.EFFSEQ = ( SELECT MAX(J3.EFFSEQ)
FROM PS_JOB J3
WHERE J3.EMPLID = J.EMPLID
AND J3.EMPL_RCD = J.EMPL_RCD
AND J3.EFFDT = J.EFFDT)
ORDER BY J.EMPLID , J.EMPL_RCD, J.EFFDT, J.EFFSEQ

Using a group by to group a select statement

Using a group by to group a select stament
SELECT
k.Ivalue, k.JOBDESCRIPTION ,
count( k.Ivalue) as TOTAL
FROM
(SELECT
a."ID" as Ivalue, b."JOBDESCRIPTION", rq."CURRENTSTATUS"
FROM
tblG2o_Requests a
INNER JOIN
tblG2o_JOBS b ON a."JOBPOSTID" = b."ID"
INNER JOIN
(SELECT
r.REQUESTID, ir."CURRENTSTATUS"
FROM
TBLG2O_RESULTSPOOL r
INNER JOIN
tblG2o_Requests ir ON r.RequestID = ir."ID"
WHERE
r.ShortListed = '1') rq ON rq.REQUESTID = a."ID"
WHERE
"ACTIVE" = '1'
AND "DATECOMPLETED" IS NULL
ORDER BY
"REQUESTDATE" DESC) k
GROUP BY
k.JOBDESCRIPTION
What is the question? You seem to be missing the group by clause, and you do not need double quotes around field names unless you have spaces in them, and even then, if TSQL for example, you would use [] in preference.
I had to remove an ORDER BY in the subquery, that isn't allowed unless other conditions demand it (like TOP n in TSQL)
SELECT
k.Ivalue
, k.JOBDESCRIPTION
, COUNT(k.Ivalue) AS TOTAL
FROM (
SELECT
a.ID AS Ivalue
, b.JOBDESCRIPTION
, rq.CURRENTSTATUS
FROM tblG2o_Requests a
INNER JOIN tblG2o_JOBS b
ON a.JOBPOSTID = b.ID
INNER JOIN (
SELECT
r.REQUESTID
, ir.CURRENTSTATUS
FROM TBLG2O_RESULTSPOOL r
INNER JOIN tblG2o_Requests ir
ON r.RequestID = ir.ID
WHERE r.ShortListed = '1'
) rqenter
ON rq.REQUESTID = a.ID
WHERE ACTIVE = '1'
AND DATECOMPLETED IS NULL
) k
GROUP BY
k.Ivalue
, k.JOBDESCRIPTION
Finally worked
SELECT
k.Ivalue
, l.JOBDESCRIPTION
, k.TOTAL,
k.CURRENTSTATUS
FROM (
SELECT
a.ID AS Ivalue
,b.ID as JobPostID
, rq."CURRENTSTATUS"
,COUNT(a.ID) AS TOTAL
FROM tblG2o_Requests a
INNER JOIN tblG2o_JOBS b
ON a."JOBPOSTID" = b.ID
INNER JOIN (
SELECT
r."REQUESTID"
, ir."CURRENTSTATUS"
FROM TBLG2O_RESULTSPOOL r
INNER JOIN tblG2o_Requests ir
ON r."REQUESTID" = ir.ID
WHERE r."SHORTLISTED" = 1
) rq
ON rq."REQUESTID" = a.ID
WHERE ACTIVE = '1'
AND DATECOMPLETED IS NULL
GROUP BY
a.ID ,b.ID
, rq."CURRENTSTATUS" ) k
inner join tblG2o_JOBS l on k.JobPostID =l.ID
enter code here