Left outer join column name ambiguously defined - sql

I have a table task
select
sts_id,
count(*) mycount
from
task
where
sts_id in (1, 8, 39)
group by sts_id;
output :
sts_id count
1 1
8 1
39 1
I have one more temp table with one column sts_id
which looks like this
sts_id
1
8
39
40
41.
I am trying for a left join for both the tables
select
in_list.sts_id,
count(*) mycount
from
task
left outer join
in_list
on task.sts_id = in_list.sts_id
group by sts_id;
to get ab o/p like
1 1
8 1
39 1
40 0
41 0..
I am getting an error of column ambiguously defined.

You are using left join the wrong way (on the left it must be the table with all the rows you want to show).
Count (task.sts_id) to get 0 on rows without ocurrences on that table
select
in_list.sts_id,
count(task.sts_id) mycount
from
in_list
left outer join
task
on in_list.sts_id = task.sts_id
AND task.sts_id in (1, 8, 39) -- Thanks Matt.
group by in_list.sts_id;

You are missing the table alias in the GROUP BY clause.
However, your needed result says that you need to change your join logic: the starting table should be in_list, while task should be in left outer join:
select ...
from in_list
left outer join task

select
in_list.sts_id,
coalesce(count(task.sts_ID),0) mycount --changed this line
from
task
right outer join --changed this line
in_list
on task.sts_id = in_list.sts_id
group by in_list.sts_id; -- changed this line
Reasons:
as in_list contains more data than task, we needed to either change the table order or make it a right join
Count would count all records and not return resutls you want the count from task
need to coalesce the results otherwise null count will return null not 0.

I got my answer with this query
select t2.sts_id, count(t.sts_id)
from task t, in_list t2
where t2.sts_id = t.sts_id(+)
group by t2.sts_id
Thanks,

Related

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

Horizontal To Vertical Sql Server

I'm stuck with a SQL query (SQL Server) that involves converting horizontal rows to vertical rows
Below is my Query that I am trying
SELECT P AS Amount_Rs
FROM (
Select (F1.D32-F1.D20) As Profit_For_The_Period ,F3.D2 as Current_Libilities,F5.D20 As Capital_Acount,
--M1.Name As Name,
F2.D20 AS Loan_Liabilities,F4.d1 As Opening_Diff --F2.D68 As Loan,
from Folio1 As F1
--inner Join Master1 As m1 on m1.Code like '101' or m1.Code Like '102' or m1.Code Like '106' or m1.Code Like '109' or m1.Code lIke '103'
--And m1.Code=102 And m1.Code=101)
inner Join Folio1 As F2 On (F2.MasterCode=F2.MasterCode)
inner Join Folio1 As F3 On (F3.MasterCode=F3.MasterCode)
inner Join Folio1 As F4 On (F4.MasterCode=F4.MasterCode)
inner Join Folio1 As F5 On (F5.MasterCode=F5.MasterCode)
Where F1.MasterCode=109
and F2.MasterCode =106
and F3.MasterCode=103
and F4.MasterCode=102
And F5.MasterCode=101
) p UNPIVOT
( p FOR value IN
( Profit_For_The_Period,Capital_Acount, Current_Libilities, Loan_Liabilities, Opening_Diff )
) AS unvpt
Current Output:
1 12392
2 0
3 0
4 4000
5 -200
Desired Output:
1 Capital Account 12392
2 Current Assets 0
3 Current Liabilities 0
4 Loans (Liability) 4000
5 Revenue Accounts -200
Thanks !!!
I think you are looking for a pivot. Use the CASE statement with a SUM or any aggregate function in the SELECT part and a group by in the where clause, that's how I use to put rows into columns in a query when I have to in MySQL. I don't know SQL Server but I think you can do quite the same.
your conditions below
F1.MasterCode=109
and F2.MasterCode =106
and F3.MasterCode=103
and F4.MasterCode=102
And F5.MasterCode=101
shouldn't be in the the where clause but with the case in the select part
example :
select whatever,
case when F2.MasterCode =106 then sum(column_name)
end case as column_alias, (other columns) from ...
hope this could help

Select row even if a condition is not true

I don't know how to ask that also this is an example.
Say I have 2 tables:
pages:
idpage title
0 first
1 second
2 third
reads:
idread idpage time
50 0 8:15
83 0 2:58
If I do SELECT * FROM pages,reads WHERE pages.idpage=reads.idpage AND pages.idpage<2
I will have something like that:
idpage title idread time
0 first 50 8:15
0 first 83 2:58
Where I would like that:
idpage title idread time
0 first 50 8:15
0 first 83 2:58
1 second 0 0:00
Thanks
Always use explicit JOIN syntax. Never use commas in the FROM clause.
What you need is a LEFT JOIN. And, the way you are expressing the query makes this much harder to figure out. So:
SELECT p.idpage, p.title,
COALESCE(idread, 0) as idread,
COALESCE(time, cast('0:00' as time)) as time
FROM pages p LEFT JOIN
reads r
ON p.idpage = r.idpage
WHERE p.idpage < 2;
Note that when using LEFT JOIN, conditions on the first table should go in the WHERE clause. Conditions on the second table go in the ON clause.
You need a left join and CASE expression to complete the values when they are null, like this:
SELECT p.*,
case when r.idread is null then 0 else r.idread end as idread
case when r.time is null then '0:00' else r.time end as time
FROM pages p
LEFT OUTER JOIN reads r
ON(p.idpage = r.idpage)
WHERE p.idpage < 2
Note that I've changed your syntax to explicit join syntax(LEFT OUTER JOIN) instead of your implicit syntax's, which can easily lead to problems, especially when left joining.
use full outer join
SELECT column_name(s)
FROM table1
FULL OUTER JOIN table2
ON table1.column_name=table2.column_name;

right join not giving values null

I have two tables as:
select * from CallTypeDescription
select * from CallTypeDetails
I want to show all the records of idcalltype against its idjob.
Eg.
If idJob in CallTypeDescription is 96 and idCallType is 4 it should show records:
if idJob is 94 (i.e. does not exists in callType description) and idCallType is 4 then result should be:
Title Value idJob
test qu1 Null Null
test qu2 Null Null
For this i tried:
select a.Title,b.Value,b.idJob from CallTypeDescription b
right join CallTypeDetails a
on a.idCallType=b.idCallType
and a.idDetails=b.idCallTypeDetail
where a.idCallType=4 and b.idJob=96
But gives me result:
It should also add another row with test qu2 null null.
Plese help me.
Edit:
select a.Title,b.Value,b.idJob from CallTypeDescription b
right join CallTypeDetails a
on a.idCallType=b.idCallType
and a.idDetails=b.idCallTypeDetail
and a.idCallType=4
where b.idJob=96
It looks like you are after this effect (SQL Fiddle: http://sqlfiddle.com/#!3/8f98e/10):
select
a.Title,b.Value,b.idJob
from
(
select
IdDesc,
IdCallType,
IdJob,
IdCallTypeDetail,
Value
from
CallTypeDescription
where
IdJob = 96 --or 94
) b
right outer join
CallTypeDetails a
on
a.idCallType=b.idCallType
and
a.idDetails=b.idCallTypeDetail
where
a.idCallType=4
Is there a reason you have chosen to use a right join instead of a left one?
Remove the line that constrains the query to only return rows where the idDetails and isCallTypeDetail are equal:
select a.Title,b.Value,b.idJob
from CallTypeDescription b inner join CallTypeDetails a
on a.idCallType=b.idCallType
where a.idCallType=4 and b.idJob=96

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.