Trouble finding a simple SQL Join Solution - sql

I looked up what I could, but could not find the same problem.
I am using the following SQL to attempt to generate the results that I am looking for.
I am trying to accomplish a join or another function that will allow me to Count or Select rows from the left side that have matching rows on the right side. If there is a matching column on the right side, I only want it to be counted once.
I am looking to see if at least one match (and count it as 1 even if they are more) for it to be counted.
This is what I am trying to do.
Left Side
Annual_Capture (ID)
1 Some Data
2 Some Data
3 Some Data
Right Side (Annual Comments)
2 Comment for Annual Capture id 2
2 Another Comment for Annual Capture id 2
Result:
From a select it would only return Annual_Capture (ID) of 2.
From a count, it would return only the record on Annual_Capture (ID 2)
In my case I keep getting a count of 2 instead of one.
Here is the SQL I am using:
COUNT:
SELECT COUNT(*) FROM Annual_Capture
JOIN Annual_Comments
ON Annual_Capture.id = Annual_Comments.Record_id
where Main_AbstractNumber = 133 and Year = 2012 ;
SELECT
SELECT * FROM Annual_Capture INNER JOIN Annual_Comments
ON Annual_Capture.id = Annual_Comments.Record_id WHERE Main_AbstractNumber = 133
AND Year = 2012
Any help would be appreciated!

select
count(distinct Annual_Capture.id)
from
Annual_Capture
inner join Annual_Comments
on Annual_Capture.id = Annual_Comments.Record_id
where
Main_AbstractNumber = 133
and Year = 2012
;

This only returns rows from Annual_Capture where there is at least one comment (which is how I read your rqmts):
SELECT Annual_Capture.id, count(Annual_Comments.*)
FROM Annual_Capture JOIN Annual_Comments ON Annual_Capture.id = Annual_Comments.Record_id
WHERE Main_AbstractNumber = 133 and Year = 2012
GROUP BY Annual_Capture.id
HAVING Count(Annual_Comments.*) >= 1;

Related

Two SELECTS return different counts, but all types of JOINS return same NUMBER of Rows, <> to either SELECT

(Using SSMS v15 against a pair of Oracle v19 dbs)
SELECT against Table1 in new management system's db1 returns 312 depreciation trxns for the month.
SELECT against View1 in old management system's db2 returns 311 depreciation transactions for the month.
Discrepancies were expected between home-brewed system and new vended one, but finding them by eyeballing results from each result set is making my eyes hurt, and I have about 4500 rows of various types of transactions to validate...each of the next three months.
I would like JOINs to show me which ones on one side are missing on the other.
And these discrepancies might go both ways.
So I'd like a statement of LEFT JOIN, showing all 312 rows from first SELECT, and NULLS for the rows that are missing from the other.
AND I'd like a statement of RIGHT JOIN, showing the 311 rows from second SELECT, and NULLS for any rows missing from the other.
However, every JOIN returns 310 rows.
I have not been through all 310 to see if the same 310 have been returned for all four JOIN types, but it's 310 rows, every time.
Not a NULL row from either side.
Possibilities:
SQL Server Mgmt Studio not playing well with Oracle?
VIEW causing some side effects?
Operator error?
Any help would be appreciated.
Thanks
select * -- = 312 rows
from Database1.ACCT_EOM_TRANSACTIONS
where period_id = '092021'
and trans_type in ('DEPRECIATION', 'OTHER FIXED 3')
order by trans_type, eq_equip_no
select * -- = 311 rows
from Database2.V_FTS_SUM
where bill_month = 9 and bill_year = 2021
and trans_type = 'DEPR'
order by trans_type, veh_ref_no
Select E.*, V.*
from Database1.ACCT_EOM_TRANSACTIONS E
JOIN Database2.V_FTS_SUM V --INNER, RIGHT OUTER, LEFT OUTER, JOIN = 310 rows
ON E.eq_equip_no = V.veh_ref_no
where E.period_id = '092021'
and E.trans_type in ('DEPRECIATION', 'OTHER FIXED 3')
and V.bill_month = 9 and V.bill_year = 2021
and V.trans_type = 'DEPR'
order by E.eq_equip_no
Your WHERE clause was breaking the outer join behavior.
To find mismatches in both left and right side, use a FULL [OUTER] JOIN, like this:
WITH cte1 AS (
select * -- = 312 rows
from ACCT_EOM_TRANSACTIONS
where period_id = '092021'
and trans_type in ('DEPRECIATION', 'OTHER FIXED 3')
)
, cte2 AS (
select * -- = 311 rows
from V_FTS_SUM
where bill_month = 9 and bill_year = 2021
and trans_type = 'DEPR'
)
SELECT *
FROM cte1 FULL JOIN cte2
ON cte1.eq_equip_no = cte2.veh_ref_no
WHERE cte1.eq_equip_no IS NULL
OR cte2.veh_ref_no IS NULL
;
Fiddle: https://dbfiddle.uk/?rdbms=oracle_18&fiddle=4c68480cdfc5b9d06d5d70ade66235e3

How to use RIGHT OUTER JOIN with GROUP BY in SQl Server 2017?

i want use ROJ in sql server with filter date but not work, i mean must return data table round null but not return how to fix problem ?
SQL Code
SELECT Lines.Target, COUNT(Round.ID) AS cnt
FROM Round RIGHT OUTER JOIN Line as Lines
on Round.Line = Lines.ID
WHERE Lines.Company = 20 AND
CAST(Round.System_Date AS DATE) BETWEEN
CAST('2019-03-01' AS DATE) AND CAST('2019-03-01' AS DATE)
GROUP BY Lines.Target
with out filter date code work
Must return =>
Target cnt
------ -----
7 0
9 0
15 0
Switch to LEFT JOIN. Move outer table condition from WHERE to ON to get true outer join result:
SELECT Lines.Target, COUNT(Round.ID) AS cnt
FROM Line as Lines
LEFT OUTER JOIN Round
on Round.Line = Lines.ID
AND CAST(Round.System_Date AS DATE) BETWEEN
CAST('2019-03-01' AS DATE) AND CAST('2019-03-01' AS DATE)
WHERE Lines.Company = 20
GROUP BY Lines.Target
Theres no BETWEEN required as its the same date you are searching for and make sure record exists for that specific date
Plus,
If you want the rounds table data being the master table then why you are using right outer join use Left Outer Join

Performance Issue in Left outer join Sql server

In my project I need find difference task based on old and new revision in the same table.
id | task | latest_Rev
1 A N
1 B N
2 C Y
2 A Y
2 B Y
Expected Result:
id | task | latest_Rev
2 C Y
So I tried following query
Select new.*
from Rev_tmp nw with (nolock)
left outer
join rev_tmp old with (nolock)
on nw.id -1 = old.id
and nw.task = old.task
and nw.latest_rev = 'y'
where old.task is null
when my table have more than 20k records this query takes more time?
How to reduce the time?
In my company don't allow to use subquery
Use LAG function to remove the self join
SELECT *
FROM (SELECT *,
CASE WHEN latest_Rev = 'y' THEN Lag(latest_Rev) OVER(partition BY task ORDER BY id) ELSE NULL END AS prev_rev
FROM Rev_tmp) a
WHERE prev_rev IS NULL
My answer assumes
You can't change the indexes
You can't use subqueries
All fields are indexed separately
If you look at the query, the only value that really reduces the resultset is latest_rev='Y'. If you were to eliminate that condition, you'd definitely get a table scan. So we want that condition to be evaluated using an index. Unfortunately a field that just values 'Y' and 'N' is likely to be ignored because it will have terrible selectivity. You might get better performance if you coax SQL Server into using it anyway. If the index on latest_rev is called idx_latest_rev then try this:
Set transaction isolated level read uncommitted
Select new.*
from Rev_tmp nw with (index(idx_latest_rev))
left outer
join rev_tmp old
on nw.id -1 = old.id
and nw.task = old.task
where old.task is null
and nw.latest_rev = 'y'
latest_Rev should be a Bit type (boolean equivalent), i better for performance (Detail here)
May be can you add index on id, task
, latest_Rev columns
You can try this query (replace left outer by not exists)
Select *
from Rev_tmp nw
where nw.latest_rev = 'y' and not exists
(
select * from rev_tmp old
where nw.id -1 = old.id and nw.task = old.task
)

Why left join is not giving distinct result?

I have following sql query and my left join is not giving me distinct result please help me to trace out.
SELECT DISTINCT
Position.Date,
Position.SecurityId,
Position.PurchaseLotId,
Position.InPosition,
ISNULL(ClosingPrice.Bid, Position.Mark) AS Mark
FROM
Fireball_Reporting.dbo.Reporting_DailyNAV_Pricing POSITION WITH (NOLOCK, READUNCOMMITTED)
LEFT JOIN Fireball.dbo.AdditionalSecurityPrice ClosingPrice WITH (NOLOCK, READUNCOMMITTED) ON
ClosingPrice.SecurityID = Position.PricingSecurityID AND
ClosingPrice.Date = Position.Date AND
ClosingPrice.SecurityPriceSourceID = #SourceID AND
ClosingPrice.PortfolioID IN (5,6)
WHERE
DatePurchased > #NewPositionDate AND
Position.Date = #CurrentPositionDate AND
InPosition = 1 AND
Position.PortfolioId IN (
SELECT
PARAM
FROM
Fireball_Reporting.dbo.ParseMultiValuedParameter(#PortfolioId, ',')
) AND
(
Position > 1 OR
Position < - 1
)
Now here in above my when I use LEFT JOIN ISNULL(ClosingPrice.Bid, Position.Mark) AS Mark and LEFT JOIN it is giving me more no of records with mutiple portfolio ids
for e.g . (5,6)
If i put portfolioID =5 giving result as 120 records
If i put portfolioID =6 giving result as 20 records
When I put portfolioID = (5,6) it should give me 140 records
but it is giving result as 350 records which is wrong . :(
It is happening because when I use LEFT JOIN there is no condition of PurchaseLotID in that as table Fireball.dbo.AdditionalSecurityPrice ClosingPrice not having column PurchaseLotID so it is giving me other records also whoes having same purchaseLotID's with diferent prices .
But I dont want that records
How can I eliminate those records ?
You get one Entry per DailyLoanAndCashPosition.PurchaseLotId = NAVImpact.PurchaseLotId
which would mean you must have more entrys in with the same PurchaseLotId
The most likely cause is that the left join produces duplicated PurchaseLotIds. The best way to know if if you perform a select distinct(PurchaseLotId) on your left side of the inner join.

How to do a subquery using the result obtained in the original query?

Here is the situation I have..I have to fetch all the associated cases for a given quoteId and this requires a join of 3 tables and I am able to come up with a query for that. Below is the sample : for brevity I have omitted some table name and used only Alias name.
SELECT distinct caseTable.CASEID, quoteHdrTable.Case_UID FROM
caseTable INNER JOIN quoteHdrTable ON
quoteHdrTable.Case_UID = caseTable.Case_UID WHERE quoteHdrTable.QUOTE_ID = '12345'.
Now for each CASE_UID that returns back, I also need to display its status from a different table. That has structure below.
STATUS_TABLE
CASE_UID STATUS
------------ -----------
123 Good
234 Bad.
345 {null}
In the end I want a result like
result
case_ID case_UID status
001 123 Good
Can we use subquery to do a 2nd SQL using the result(case_UID) from first..please provide pointers or a sample SQL statement.
FYI..using DB2 database
Thanks
Sandeep
SELECT distinct c.CASEID, q.Case_UID, s.status
FROM caseTable c
INNER JOIN quoteHdrTable q ON q.Case_UID = c.Case_UID
LEFT JOIN StatusTable s ON s.CASE_UID = q.CASE_UID
WHERE quoteHdrTable.QUOTE_ID = '12345'
Why not just add another JOIN?
SELECT distinct
caseTable.CASEID,
quoteHdrTable.Case_UID,
status.STATUS
FROM caseTable
INNER JOIN quoteHdrTable
ON quoteHdrTable.Case_UID = caseTable.Case_UID
INNER JOIN STATUS_TABLE status
ON quoteHdrTable.Case_UID = status.Case_UID
WHERE quoteHdrTable.QUOTE_ID = '12345'