Select Distinct Value from Multiple tables, Where One has Multiples - sql

I have searched for this problem but have not found anything quite like it. I have two tables, both with a field, FormID. In table A, FormID is unique. In table B, there can be multiple records with the same FormID -- table B is a problem tracker table, so if there are multiple data entry problems in the form, there will be multiple records in there.
The following query works:
select distinct b.FormID
from b
where b.FormID = a.FormID
and a.status='done'
as far it does generate a result list of unique FormIDs. However, I also need to get some other columns in this query and it's when I add those columns to the select or the join that I get ALL the duplicate FormIDs.
I have tried:
select distinct (b.FormID), a.FormType, a.Site, a.uid, b.ProbID, b.Date
from b, a
where b.FormID = a.FormID
and a.status='done'
as well as a couple of variations using joins, but they all end up with all the rows with duplicate FormIDs.
Suggestions?

Try
SELECT b.FormID,
MAX(a.FormType) FormType,
MAX(a.Site) Site,
MAX(a.uid) uid,
MAX(b.ProbID) ProbID,
MAX(b.Date) Date
FROM b INNER JOIN
a ON b.FormID = a.FormID
WHERE a.status='done'
GROUP BY b.FormID

Related

SQL Server : get unique ID from one table, another table, or both

I have two tables, TA and CMI, that contain a person_ID. The ID may exist in TA, it may exist in CMI, or it may exist in both. I want a distinct list of ALL person_ID's regardless whether they are in TA, CMI, or both tables.
I also want to be able to select them where their question_ID's are the same. However, the question_id's have different column names: TA.question and CMI.sco = question_id.
EDIT:
So, if I also wanted to do the select on question as I stated earlier AND a join to the person table, it would look something like:
select ta.person_id, person_key
from ta
left join person on person.person_id = ta.person_id
where question=7033
union -- on purpose to remove duplicates
select cmi.person_id, person_key
from cmi
left join person on person.person_id = cmi.person_id
where sco=7033
You would use union:
select person_id
from ta
union -- on purpose to remove duplicates
select person_id
from cmi;
You can use this as a CTE or subquery in a query.

Retrieve a row from multiple tables on Oracle [one or more tables are empty]

When having multiple tables with different columns, I would like to add all of them as one record. However, when one of them doesn't have records,
the other records retrieved from the other tables are not shown. How can I show the results of the remaining tables? For example, I have three
tables with one catalogue. Suppose that Table A doesn't have records and table B and C have. How can I show the results for these tables (Table B and C)? Even when Table A doesn't have records.
For example:
Table A
RECN
FNAME
TABLE B
RECN
DATE
TABLE C
RECN
ATTR1
Table CAT
RECN
LABEL
SELECT TA.*,TB.*,TC.*
FROM
(SELECT A.RECN, A.FNAME, CAT.LABEL
FROM A, CAT
WHERE A.RECN= CAT.RECN) TA,
(SELECT B.RECN, B.DATE, CAT.LABEL
FROM B, CAT
WHERE B.RECN=CAT.RECN) TB,
(SELECT C.RECN, C.ATTR1, CAT.LABEL
FROM C, CAT
WHERE C.RECN=CAT.RECN) TC
Now, I am obtaining an empty row, but I have to show the values of the tables which include values.
Thank you in advance for your help
Use LEFT JOIN. In addition, the subqueries -- while not a problem -- are not needed. In fact, your JOIN syntax is wrong. Here is what the query should look like:
SELECT A.RECN, A.FNAME, CAT.LABEL,
B.RECN, B.DATE, CAT.LABEL,
C.RECN, C.ATTR1, CAT.LABEL
FROM TA LEFT JOIN
TB
ON B.RECN = CAT.RECN LEFT JOIN
TC
C.RECN = CAT.RECN;

SQL Query linking tables, returning the earliest history from one table with the associated result

I have two tables which I need to query. Let's call them table A, and table A_HISTORIES.
Each row from Table A, is linked to multiple rows in A_HISTORIES. What I want to do is to be able to link each row from table A with its earliest history from table A_HISTORIES so something like:-
SELECT A.*
A_HISTORIES.CREATED_DATE
FROM A, A_HISTORIES
WHERE A.ID = A_HISTORIES.A_ID
AND A_HISTORIES.ID = (SELECT max(id) keep (dense_rank first order by CREATED_DATE)
FROM A_HISTORIES)
However, this will only return the row from A/A_HISTORIES that has the earliest CREATED_DATE. Can anyone help me do this per row in A?
Thanks
How about something like this:
SELECT A.*
A_HISTORIES.CREATED_DATE
FROM A
INNER JOIN A_HISTORIES ON A.ID = A_HISTORIES.A_ID
INNER JOIN (SELECT A_ID, MAX(CREATE_DATE) AS max_create_date
FROM A_HISTORIES
GROUP BY A_ID) max_hist ON A_HISTORIES.A_ID = max_hist.A_ID
AND A_HISTORIES.ceate_date = max_create_date

Self Join bringing too many records

I have this query to express a set of business rules.
To get the information I need, I tried joining the table on itself but that brings back many more records than are actually in the table. Below is the query I've tried. What am I doing wrong?
SELECT DISTINCT a.rep_id, a.rep_name, count(*) AS 'Single Practitioner'
FROM [SE_Violation_Detection] a inner join [SE_Violation_Detection] b
ON a.rep_id = b.rep_id and a.hcp_cid = b.hcp_cid
group by a.rep_id, a.rep_name
having count(*) >= 2
You can accomplish this with the having clause:
select a, b, count(*) c
from etc
group by a, b
having count(*) >= some number
I figured out a simpler way to get the information I need for one of the queries. The one above is still wrong.
--Rep violation for different HCP more than 5 times
select distinct rep_id,rep_name,count(distinct hcp_cid)
AS 'Multiple Practitioners'
from dbo.SE_Violation_Detection
group by rep_id,rep_name
having count(distinct hcp_cid)>4
order by count(distinct hcp_cid)

Rewrite SQL and use of group by

I have written below sql for one of the requirement and is fetching my results. But, I am wondering if there is any better way of writing this query rather than using alias table as A.
SELECT A.*,B.OPRDEFNDESC FROM
( select OPRID_ENTERED_BY ,COUNT(*)
from ps_req_hdr
where entered_dt > '01-JUL-2012'
GROUP BY OPRID_ENTERED_BY
ORDER BY COUNT(*) DESC) A, PSOPRDEFN B
WHERE A.OPRID_ENTERED_BY=B.OPRID
You may be able to use a simple INNER JOIN to do the same thing...
SELECT A.OPRID_ENTERED_BY, COUNT(*), B.OPRDEFNDESC
FROM ps_req_hdr A
JOIN PSOPRDEFN B ON A.OPRID_ENTERED_BY = B.OPRID
WHERE A.entered_dt > '01-JUL-2012'
GROUP BY A.OPRID_ENTERED_BY, B.OPRDEFNDESC
ORDER BY COUNT(*) DESC
NOTE
As per the comments below, the COUNT(*) result for this query will NOT include records that don't have corresponding matches in table B, and it will inflate for non-unique matches in table B. What this means is: if B.OPRID is not a unique field or if A.OPRID_ENTERED_BY is not a foreign key for B.OPRID then this answer will not yield the same results as the original query.