Show column value of one of left joins - sql

In this Query shows one row if SAL.ID_AMENAZA exists in MFT or MFA schemas, but i want to show MFT.ID_AMENAZA or MFA.ID_AMENAZA (if exist in any table) in the resulting row.
In my actual query i dont require the ID_AMENAZA. How can i show?
SELECT SAL.ID_SALVAGUARDA, SAL.DESCRIPCION, SAL.EFICACIA
FROM AGR_SALVAGUARDAS SAL
LEFT JOIN AGR_MIT_FREC_TIPO MFT
ON SAL.ID_SALVAGUARDA = MFT.ID_SALVAGUARDA AND MFT.ID_AMENAZA = 5043
LEFT JOIN AGR_MIT_FREC_ACT MFA
ON SAL.ID_SALVAGUARDA = MFA.ID_SALVAGUARDA AND MFA.ID_AMENAZA = 5043
WHERE MFT.ID_SALVAGUARDA IS NOT NULL OR
MFA.ID_SALVAGUARDA IS NOT NULL
GROUP BY SAL.ID_SALVAGUARDA, SAL.DESCRIPCION, SAL.EFICACIA
I need to obtain a table like this:
ID_SALVAGUARDA | DESCRIPCION | EFICACIA | ID_AMENAZA
5061 | PRE-01 | 100 | 5043
Thank you in advance.

This should work for you:
SELECT SAL.ID_SALVAGUARDA, SAL.DESCRIPCION, SAL.EFICACIA, 5043 as ID_AMENAZA
FROM AGR_SALVAGUARDAS SAL
LEFT JOIN AGR_MIT_FREC_TIPO MFT
ON SAL.ID_SALVAGUARDA = MFT.ID_SALVAGUARDA AND MFT.ID_AMENAZA = 5043
LEFT JOIN AGR_MIT_FREC_ACT MFA
ON SAL.ID_SALVAGUARDA = MFA.ID_SALVAGUARDA AND MFA.ID_AMENAZA = 5043
WHERE MFT.ID_SALVAGUARDA IS NOT NULL OR
MFA.ID_SALVAGUARDA IS NOT NULL
GROUP BY SAL.ID_SALVAGUARDA, SAL.DESCRIPCION, SAL.EFICACIA;
because your query guarantees that there is at least one match.
However, the more general solution is:
SELECT SAL.ID_SALVAGUARDA, SAL.DESCRIPCION, SAL.EFICACIA,
cOALESCE(MFT.ID_AMENAZA, MFA.ID_AMENAZA) as ID_AMENAZA
. . .
The function COALESCE() returns the first value that is not NULL in its list of arguments.

You can coalesce for this.
SELECT
SAL.ID_SALVAGUARDA,
SAL.DESCRIPCION,
SAL.EFICACIA,
COALESCE( MFT.ID_AMENAZA, MFA.ID_AMENAZA) as ID_AMENAZA
This will return the first ID that is not null.

Related

Select highest value based off of a different column

I am trying to get the highest value based off of another column.
SELECT DISTINCT
AppDetailVehicleValuation.AppID,
VehicleValuationOption.Description,
MAX (VehicleValuationOptionValueType.Value)
FROM
AppDetailVehicleValuation
INNER JOIN VehicleValuationOption
ON AppDetailVehicleValuation.ValuationID = VehicleValuationOption.ValuationID
INNER JOIN VehicleValuationOptionValueType
ON VehicleValuationOption.ValuationOptionID = VehicleValuationOptionValueType.ValuationOptionID
WHERE
(VehicleValuationOption.IsSelected LIKE '1')
AND (VehicleValuationOption.IsSystemOption LIKE '1')
What I have is this
AppID | Description | Value
999 Beats Audio 425.00
999 Beats Audio 475.00
999 Power Str. 600.00
999 Power Str. 750.00
this is what I need
AppID | Description | Value
999 Beats Audio 475.00
999 Power Str. | 750.00
You are just missing a GROUP BY clause in your query:
SELECT
AppDetailVehicleValuation.AppID,
VehicleValuationOption.Description,
MAX (VehicleValuationOptionValueType.Value)
FROM
AppDetailVehicleValuation
INNER JOIN VehicleValuationOption
ON AppDetailVehicleValuation.ValuationID = VehicleValuationOption.ValuationID
INNER JOIN VehicleValuationOptionValueType
ON VehicleValuationOption.ValuationOptionID = VehicleValuationOptionValueType.ValuationOptionID
WHERE
(VehicleValuationOption.IsSelected LIKE '1')
AND (VehicleValuationOption.IsSystemOption LIKE '1')
GROUP BY AppDetailVehicleValuation.AppID, VehicleValuationOption.Description
You can simply do this:
SELECT
t.AppId,
t.Description,
max(t.Value)
FROM mytable t
GROUP BY t.description, t.AppId
This is too long for a comment.
Glad you found an answer that works with the GROUP BY. I would suggest you start using aliases in your queries. It can quickly and easily turn a wall of text into something fairly easy to see what is going on. You might end with something along these lines.
SELECT advv.AppID
, vvo.Description
, MaxValue = MAX(vvot.Value)
FROM AppDetailVehicleValuation advv
INNER JOIN VehicleValuationOption vvo ON advv.ValuationID = vvo.ValuationID
INNER JOIN VehicleValuationOptionValueType vvot ON vvo.ValuationOptionID = vvot.ValuationOptionID
WHERE vvo.IsSelected = '1'
AND vvo.IsSystemOption = '1'
group by advv.AppID
, vvo.Description

How to Get a Count of Records Using Partitioning in Oracle

I have the following query:
SELECT
F.IID,
F.E_NUM AS M_E_NUM,
MCI.E_NUM AS MCI_E_NUM,
F.C_NUM AS M_C_NUM,
MCI.C_NUM AS MCI_C_NUM,
F.ET_ID AS M_ET_ID,
EDIE.ET_ID AS ED_INDV_ET_ID,
COUNT(*) OVER (PARTITION BY F.IID) IID_COUNT
FROM FT_T F JOIN CEMEI_T MCI ON F.IID = MCI.IID
JOIN EDE_T EDE ON MCI.E_NUM = EDE.E_NUM
JOIN EDIE_T EDIE ON EDIE.IID = F.IID AND EDIE.ET_ID = EDE.ET_ID
WHERE
F.DEL_F = 'N'
AND MCI.EFF_END_DT IS NULL
AND MCI.TOS = 'BVVB'
AND EDE.PTEND_DT IS NULL
AND EDE.DEL_S = 'N'
AND EDE.CUR_IND = 'A'
AND EDIE.TAR_N = 'Y'
AND F.IID IN
(
SELECT DISTINCT IID
FROM FT_T
WHERE GROUP_ID = 'BG'
AND DEL_F = 'N'
AND (IID, E_NUM) NOT IN
(
SELECT IID, E_NUM FROM CEMEI_T
WHERE TOS = 'BVVB' AND EFF_END_DT IS NULL
)
);
I am basically grabbing information from several tables and creating a flat record of them.
Everything works accordingly except now I need to find out whether there are two records in FT_T table with identical IID's and display that count as part of the result set.
I tried to use partitioning but all the rows in the result set return a single count even though there are ones that have 2 records with identical IID's in FT_T.
The reason I initially said that I'm gathering information from several tables is due to the fact that FT_T might not have all the information I need if two records are not available for the same IID, so I have to retrieve them from other tables JOINed in the query. However, I need to know which FT_T.IID's have two records in FT_T (or greater than one).
Perhaps you need to calculate the count before the join and filtering:
SELECT . . .
FROM (SELECT F.*,
COUNT(*) OVER (PARTITION BY F.IID) as IID_CNT
FROM FT_T F
) JOIN
CEMEI_T MCI
ON F.IID = MCI.IID JOIN
EDE_T EDE
ON MCI.E_NUM = EDE.E_NUM JOIN
EDIE_T EDIE
ON EDIE.IID = F.IID AND EDIE.ET_ID = EDE.ET_ID
. . .
this is merely a comment/observation, but formatting is needed
You use of in(...) with select distinct and not in(...,...) seems complex and could be a problem if some values are NULL. I suggest you consider using EXISTS and NOT EXISTS instead. e.g.
AND EXISTS (
SELECT
NULL
FROM FT_T
WHERE F.IID = FT_T.IID
AND FT_T.GROUP_ID = 'BG'
AND FT_T.DEL_F = 'N'
AND NOT EXISTS (
SELECT
NULL
FROM CEMEI_T
WHERE FT_T.IID = CEMEI_T.IID
AND FT_T.E_NUM = CEMEI_T.E_NUM
AND CEMEI_T.TOS = 'BVVB'
AND CEMEI_T.EFF_END_DT IS NULL
)
)

How to conditionally join two tables

I have two tables which I need to join depending upon their values.
TABLE coursemat
+-----+--------+----------+
| txt | price | material |
+-----+--------+----------+
Table coprices
+--------+----------+
| price | material |
+--------+----------+
They are connected by the material key.
If I search coursemat.material and find that coprices.material is equal, then I must use coprices.price instead of the coursemat.price.
This is what I have so far:
SELECT coursemat.txt, coursemat.price, coursemat.material, coprices, country
FROM coursemat
JOIN corprices ON coursemat.material = coprices.material;
But this isn't quite getting what I want.
Essentially, I want to use coursemat.price if coprices.price does not exist for the same material and coprices.material does exist, then I want to use coprices.price instead of coursemat.price.
If I understand what you want correctly you can use a left join and the IFNULL statement:
SELECT
coursemat.txt,
IFNULL(coprices.price, coursemat.price),
coursemat.material,
coprices.country
FROM
coursemat
LEFT JOIN
corprices
ON coursemat.material = coprices.material;
Another option is COALESCE:
SELECT cm.txt, cm.material, COALESCE(cp.price, cm.price) AS price
FROM coursemat cm
LEFT JOIN corprices cp ON cm.material = cp.material;
Finally, you could also use a CASE statement:
SELECT cm.txt, cm.material,
CASE WHEN cp.price IS NOT NULL THEN cp.price ELSE cm.price END AS price
FROM coursemat cm
LEFT JOIN corprices cp ON cm.material = cp.material;

how to join two tables where second table has condtion

I have two tables like
shopping_cart_table and customer_table
shopping_cart_table has fields shoppingcart_id | home_No|
customer_table has fields shoppingcart_id | status| customer_type|
I want to get the home_No from shopping_cart_table WHERE (customer_table.status is null OR customer_table.status='Y') AND customer_table.customer_type='X'
both table can join from shoppingcart_id
Actually this is just basic.
You can use join & put where conditions.
Select a.home_No
from shopping_cart_table as a
inner join customer_table as b
on a.shoppingcart_id = b.shoppingcart_id
where nvl(b.status,'Y') = 'Y'
and customer_type='X'
select home_No
from shopping_cart_table, customer_table
WHERE shopping_cart_table.shoppingcart_id = customer_table.shoppingcart_id
AND(customer_table.status is not null OR customer_table.status='Y') AND
customer_table.customer_type='X'
But this condition looks a bit strange:
(customer_table.status is not null OR customer_table.status='Y')
Maybe you'd want to change it for
nvl(customer_table.status,'Y')='Y'
aqssuming that 'not' was put there by a mistake
You can try this query:
SELECT sct.home_no
FROM shopping_cart_table AS sct
, customer_table AS ct
WHERE sct.shoppingcart_id = ct.shoppingcart_id
AND (
ct.status IS NOT NULL
OR ct.status = 'Y')
AND ct.customer_type = 'X'

Merge multiple rows in data to show only a single row in the result

I have a stored procedure which takes 1 parameter, an ID number (systudentid).
The procedure returns 3 rows: a student’s academic counselor (AC), financial counselor (FC), and admissions counselor (EC) along with relevant contact information; 3 different people.
Certain students have ACs and FCs who are the same person, but the query will still return 3 rows.
AdvisorType|AdvisorLastName|AdvisorFirstName|(other data)|systaffID
AC DOE JOHN ..... 12345
AC DOE JOHN ..... 12345
EC SMITH JANE ..... 45678
Where in my code can I plug in the logic (and how, I'm a newbie with sql) so that when the systudentid passed to the procedure identifies a student having the same person for both AC and FC, it will display the results this way.
The advisor type is changed to "SSA" and only one of the records for the double-duty counselor is returned.
AdvisorType|AdvisorLastName|AdvisorFirstName|(other data)|SystaffID
SSA DOE JOHN ...... 12345
EC SMITH JANE ...... 45678
Here is my select statement:
SELECT
SyStaffGroup.Descrip AS AdvisorType
,SyStaff.LastName AS AdvisorLastName
,SyStaff.FirstName AS AdvisorFirstName
,SyStaff.Phone AS AdvisorPhone
,SyStaff.Ext AS AdvisorExtention
,SyStaff.eMail AS AdvisorEMail
,SyStaff.SyStaffID AS SyStaffID
FROM SyStaff (NOLOCK)
JOIN SyAdvisorByEnroll (NOLOCK)
ON SyAdvisorByEnroll.SyStaffID = SyStaff.SyStaffID
JOIN SyStaffGroup (NOLOCK)
ON SyStaffGroup.SyStaffGroupID = SyAdvisorByEnroll.SyStaffGroupID
JOIN AdEnroll (NOLOCK)
ON AdEnroll.AdEnrollID = SyAdvisorByEnroll.AdEnrollID
JOIN SyStudent (NOLOCK)
ON AdEnroll.SyStudentID = SyStudent.SyStudentId
WHERE
SyStaff.Active = 1
--AND
--syadvisorbyenroll.adenrollid = (
--SELECT adenrollid from dbo.fn_student_enrollment_activeenrollmentlist (#systudentid)
--)
AND adEnroll.adEnrollID IN (
SELECT adEnrollID FROM dbo.fn_Student_Enrollment_ActiveEnrollmentList(#SyStudentID)
)
AND SyAdvisorByEnroll.AdvisorModule IN ('AD','FA')
AND SyStaffGroup.Descrip IN ('AC - Academic Counselor', 'FC - Finance Counselors', 'EC - Adm. Counselor With Reg')
UNION
SELECT DISTINCT
'Admissions Counselor' AS AdvisorType
,SyStaff.LastName AS AdvisorLastName
,SyStaff.FirstName AS AdvisorFirstName
,SyStaff.Phone AS AdvisorPhone
,SyStaff.Ext AS AdvisorExtention
,SyStaff.eMail AS AdvisorEMail
,SyStaff.SyStaffID AS SyStaffID
FROM systudent
INNER JOIN AmRep ON SyStudent.AMREpID = AmREp.AMREpid
INNER JOIN SyStaff ON SyStaff.SyStaffID = AmRep.AmRepID
WHERE Systudent.SYStudentid = #systudentid
Any hints or suggested methods that I can either try or Google (I've tried searching but results are a lot more useful if I knew what to look for) would be greatly appreciated.
You can add a nested subquery to indicate which students have the same advisor filling multiple positions, and adjust the type selection accordingly. Here are the changed portions of your above query:
SELECT
CASE WHEN (mutiples.SyStaffID IS NOT NULL) THEN 'SSA'
ELSE SyStaffGroup.Descrip END AS AdvisorType
-- other columns omitted
FROM SyStaff (NOLOCK)
JOIN SyAdvisorByEnroll (NOLOCK)
ON SyAdvisorByEnroll.SyStaffID = SyStaff.SyStaffID
LEFT JOIN (
SELECT SyStaffID,AdEnrollID
FROM SyAdvisorByEnroll
GROUP BY SyStaffID,AdEnrollID
HAVING COUNT(DISTINCT SyStaffGroupID) > 1
) multiples
ON multiples.SyStaffID = SyAdvisorByEnroll.SyStaffID
AND multiples.AdEnrollID = SyAdvisorByEnroll.AdEnrollID
-- rest of query omitted
This might have a mistake or two, since you didn't include your table schema. The nested subquery, "multiples", contains all advisor / enrollee pairs where the advisor is in multiple groups. You left join against this and adjust the final type selection to "SSA" if there's a matching entry in the nested subquery.
An important note: as written, this will include two SSA rows for an eligible advisor / enrollee pair. However, the final results will not, because you are using a UNION in this query, which filters out duplicates, even if they're only present in one half of the union. If you change this to UNION ALL or eliminate the UNION entirely, you will need to add DISTINCT to the top of the query, like so:
SELECT DISTINCT CASE WHEN (mutiples.SyStaffID IS NOT NULL) ...