Incorrect count value in subquery on table join column - sql

The query I'm executing seems to be ignoring the where clause in the subquery
(select count(amazon) from orders where b.amazon = 2 and manifest = a.dbid)
column amazon is type INT
SQL SERVER 2014
If I run the query on its own and enter the value for manifest I get the correct result which I am expecting and is 1
select count(amazon) from orders where amazon = 2 and manifest = '211104'
Result Returns 1
When I run the query below I get a result of 5 which is the count of all orders where manifest = 211104 but the value of amazon is 1 in 4 results and 2 in 1 result.
Select distinct
top 30 DBID, today ,sum([amazon-orders])
From
(
SELECT [dbid], [today],
(select count(amazon) from orders
where b.amazon = 2 and manifest = a.dbid) as [amazon-orders]
FROM [manifest] a
join orders b on a.[dbid] = b.[manifest]
) t1
Group By
DBID, today
order by dbid desc
Can someone please help me.
Thanks

You have an extra join so you are counting multiple times... do this:
Select distinct
top 30 DBID, today ,sum([amazon-orders])
From
(
SELECT [dbid], [today],
(select count(amazon) from orders b
where b.amazon = 2 and manifest = a.dbid) as [amazon-orders]
FROM [manifest] a
) t1
Group By
DBID, today
order by dbid desc
or like this
SELECT [dbid], [today], count(o.amazon)
FROM [manifest] a
join orders o on a.dbid = o.manifest and o.amazon = 2
group by dbid, today
or this if you have columns you don't want to join (there is more going on than just this one join in your query and you need to use a left join):
SELECT [dbid], [today], sum(case when o.amazon is not null then 1 else 0 end)
FROM [manifest] a
left join orders o on a.dbid = o.manifest and o.amazon = 2
group by dbid, today

How's this?
SELECT top 30 [dbid], [today], sum(case when b.amazon = 2 then 1 else 0 end) as [amazon-orders]
FROM [manifest] a
join orders b on a.[dbid] = b.[manifest]
group by DBID, today
order by dbid desc
Pretty sure that because your query is in effect joining orders twice it's increasing the count.

Use this :
select a.DBID, a.today, count(b.amazon) from [manifest] a
join orders b on a.[dbid] = b.[manifest] and b.amazon = 2
Group By a.DBID, a.today

Related

SQL Query 1 have count Function and to get data from another SQL Query 2 where memberid is same

My First Query is
SELECT
memberid,
count(*) count
From
dbo.Transactions
group by
dbo.Transactions.MemberID
having
count(memberid) > 1
My query 2 is
SELECT
transactionlog.id,
transactionlog.transactionid,
transactionlog.transactionamount,
transactionlog.transactiondate,
transactions.MemberID,
GymMember.FirstName,
from
dbo.GymMember
inner join Transactions on
GymMember.MemberID = Transactions.MemberId
inner join TransactionLog on
Transactions.Id = TransactionLog.TransactionId
Results of Query 2 are givne in below image
Now i want to have data where query 1 member id and query 2 member id are same
Do you mean find data where the MemberID from the second query exists in the first query? If so please see query below.
SELECT
transactionlog.id,
transactionlog.transactionid,
transactionlog.transactionamount,
transactionlog.transactiondate,
transactions.MemberID,
GymMember.FirstName,
from
dbo.GymMember
inner join Transactions on
GymMember.MemberID = Transactions.MemberId
inner join TransactionLog on
Transactions.Id = TransactionLog.TransactionId
WHERE
Transactions.MemberId IN
(SELECT
memberid
FROM
dbo.Transactions
group by
dbo.Transactions.MemberID
having
count(memberid) > 1))
I was working on it from more than 24 hours and after try and trial i found the solution but Senior can recommend a more proper way to do this My Solution is
SELECT* FROM( SELECT* FROM
(select transactionlog.id, transactionlog.transactionid, transactionlog.transactionamount, transactionlog.transactiondate, transactions.MemberID, GymMember.FirstName, GymMember.CellNumber from dbo.GymMember
inner join Transactions on GymMember.MemberID = Transactions.MemberId
inner join TransactionLog on Transactions.Id = TransactionLog.TransactionId) as MYTABLE where Exists
(select dbo.transactions.memberid,count(dbo.transactions.memberid) From dbo.Transactions Where mytable.MemberID = dbo.Transactions.MemberID group by dbo.Transactions.MemberID having count(dbo.Transactions.MemberID) > 1)) AS mynewtable where convert(datetime,TransactionDate,103) between '2022-09-30 00:00:00' and '2022-10-01 00:00:00'

How do you properly query the result of a complex join statement in SQL?

New to advanced SQL!
I'm trying to write a query that returns the COUNT(*) and SUM of the resulting columns from this query:
DECLARE #Id INT = 1000;
SELECT
*,
CASE
WHEN Id1 >= 6 THEN 1
ELSE 0
END AS Tier1,
CASE
WHEN Id1 >= 4 THEN 1
ELSE 0
END AS Tier2,
CASE
WHEN Id1 >= 2 THEN 1
ELSE 0
END AS Tier3
FROM (
SELECT
Org.OrgID,
App.AppID,
App.FirstName,
App.LastName,
MAX(AppSubmitU_Level.Id1) AS Id1
FROM Org
INNER JOIN AppEmployment
ON AppEmployment.OrgID = Org.OrgID
INNER JOIN App
ON App.AppID = AppEmployment.AppID
INNER JOIN AppSubmit
ON App.AppID = AppSubmit.AppID
INNER JOIN AppSubmitU_Level
ON AppSubmit.LevelID = AppSubmitU_Level.Id1
INNER JOIN AppEmpU_VerifyStatus
ON AppEmpU_VerifyStatus.VerifyStatusID = AppEmployment.VerifyStatusID
WHERE AppSubmitU_Level.SubmitTypeID = 1 -- Career
AND AppEmpU_VerifyStatus.StatusIsVerified = 1
AND AppSubmit.[ExpireDate] IS NOT NULL
AND AppSubmit.[ExpireDate] > GETDATE()
AND Org.OrgID = #Id
GROUP BY
Org.OrgID,
App.AppID,
App.FirstName,
App.LastName
) employees
I've tried to do so by moving the #Id outside the original query, and adding a SELECT(*), SUM, and SUM to the top, like so:
DECLARE #OrgID INT = 1000;
SELECT COUNT(*), SUM(employees.Tier1), SUM(employees.Tier2), SUM(employees.Tier3)
FROM
(SELECT *,
...
) AS employees
);
When I run the query, however, I'm getting the errors:
The multi-part identifier employees.Tier1 could not be bound
The same errors appear for the other identifiers in my SUM statements.
I'm assuming this has to do with the fact that the Tier1, Tier2, and Tier3 columns are being returned by the inner join query in my FROM(), and aren't values set by the existing tables that I'm querying. But I can't figure out how to rewrite it to initialize properly.
Thanks in advance for the help!
This is a scope problem: employees is defined in the subquery only, it is not available in the outer scope. You basically want to alias the outer query:
DECLARE #OrgID INT = 1000;
SELECT COUNT(*), SUM(employees.Tier1) TotalTier1, SUM(employees.Tier2) TotalTier2, SUM(employees.Tier3) TotalTier3
FROM (
SELECT *,
...
) AS employees
) AS employees;
--^ here
Note that I added column aliases to the outer query, which is a good practice in SQL.
It might be easier to understand what is going on if you use another alias for the outer query:
SELECT COUNT(*), SUM(e.Tier1), SUM(e.Tier2), SUM(e.Tier3)
FROM (
SELECT *,
...
) AS employees
) AS e;
Note that you don't actually need to qualify the column names in the outer query, since column names are unambigous anyway.
And finally: you don't actually need a subquery. You could write the query as:
SELECT
SUM(CASE WHEN Id1 >= 6 THEN 1 ELSE 0 END) AS TotalTier1,
SUM(CASE WHEN Id1 >= 4 THEN 1 ELSE 0 END) AS TotalTier2,
SUM(CASE WHEN Id1 >= 2 THEN 1 ELSE 0 END) AS TotalTier3
FROM (
SELECT
Org.OrgID,
App.AppID,
App.FirstName,
App.LastName,
MAX(AppSubmitU_Level.Id1) AS Id1
FROM Org
INNER JOIN AppEmployment
ON AppEmployment.OrgID = Org.OrgID
INNER JOIN App
ON App.AppID = AppEmployment.AppID
INNER JOIN AppSubmit
ON App.AppID = AppSubmit.AppID
INNER JOIN AppSubmitU_Level
ON AppSubmit.LevelID = AppSubmitU_Level.Id1
INNER JOIN AppEmpU_VerifyStatus
ON AppEmpU_VerifyStatus.VerifyStatusID = AppEmployment.VerifyStatusID
WHERE AppSubmitU_Level.SubmitTypeID = 1 -- Career
AND AppEmpU_VerifyStatus.StatusIsVerified = 1
AND AppSubmit.[ExpireDate] IS NOT NULL
AND AppSubmit.[ExpireDate] > GETDATE()
AND Org.OrgID = #Id
GROUP BY
Org.OrgID,
App.AppID,
App.FirstName,
App.LastName
) employees

Select one row that is a duplicate and also select the other rows that are not duplicates

here is my code
select i.RefNo,i.Premium,i.Description from (select d.Description,c.IsActiveRecord,c.RefNo,c.MovementID, c.Premium,ROW_NUMBER()
over(partition by c.premium order by c.refno) n from lif_mgm_t_contract c
inner join SDT_LJG_T_MovementDescription d with (nolock) on c.MovementID = d.MovementID ) i
where i.n = 1 and i.MovementID <> 0
so for instance
table
a
a
b
I want the query to return
a
b and not just a hope this makes sense --only a beginner
try using a group by clause
SELECT OrderNumber
FROM AccountOrder
group by OrderNumber
so if my table has the following order numbers
1
2
2
3
the query would return
1
2
3

Display Y/N column if record found in detail table

I'm trying to create a query so that I can have a column show Y/N if a particular item was ordered for a group of orders. The item I'm looking for would be OLI.id = '538'.
So my results would be:
Order#, Customer#, FreightPaid
12345, 00112233, Y
12346, 00112233, N
I cannot figure out if I need to use a subquery or the where exists function ?
Here's my current query:
SELECT distinct
OrderID,
Accountuid as Customerno
FROM [SMILEWEB_live].[dbo].[OrderLog] OL
inner join Orderlog_item OLI on OLI.orderlogkey = OL.[key]
inner join Account A on A.uid = OL.Accountuid
where A.GroupId = 'X9955'
and OL.CreateDate >= GETDATE() - 60
I would suggest an exists clause instead of a join:
select ol.OrderID, ol.Accountuid as Customerno,
(case when exists (select 1
from Orderlog_item OLI join
Account A
on A.uid = OL.Accountuid
where OLI.orderlogkey = OL.[key] and A.GroupId = 'X9955'
)
then 1 else 0
end) as flag
from [SMILEWEB_live].[dbo].[OrderLog] OL
where OL.CreateDate >= GETDATE() - 60;
This prevents a couple of problems. First, duplicate rows which are caused when there are multiple matching rows (and select distinct add unnecessary overhead). Second, missing rows, which happen when you use inner join instead of an outer join.

How to use multiple count and where condition sql server 2008?

I have this two query
1.
select CL_Clients.cl_id,CL_Clients].cl_name,COUNT(*) AS number_of_orders
from CL_Clients,CLOI_ClientOrderItems
where CL_Clients.cl_id=CLOI_ClientOrderItems.cl_id
group by CL_Clients.cl_name,CL_Clients.cl_id
2.
select CL_Clients.cl_id,count(cloi_current_status) as dis
from CLOI_ClientOrderItems,CL_Clients
where cloi_current_status]='12'
and CL_Clients.cl_id=CLOI_ClientOrderItems.cl_id
group by CL_Clients.cl_name,CL_Clients.cl_id,CLOI_ClientOrderItems.cloi_current_status
i have this column i need to put count function and where condition
[cloi_current_status]
166
30
30
30
150
150
150
150
150
150
150
Quite simple, you just encapsulate the queries and give their result sets an alias and then do a JOIN between their aliases on the column that is common. (In the query below I assume you'll be joining by client id)
SELECT *
FROM (
SELECT CL_Clients.cl_id,
CL_Clients].cl_name,
COUNT(*) AS number_of_orders
FROM CL_Clients,
CLOI_ClientOrderItems
WHERE CL_Clients.cl_id = CLOI_ClientOrderItems.cl_id
GROUP BY CL_Clients.cl_name,
CL_Clients.cl_id
) A
INNER JOIN (
SELECT CL_Clients.cl_id,
count(cloi_current_status) AS dis
FROM CLOI_ClientOrderItems,
CL_Clients
WHERE cloi_current_status] = '12'
AND CL_Clients.cl_id = CLOI_ClientOrderItems.cl_id
GROUP BY CL_Clients.cl_name,
CL_Clients.cl_id,
CLOI_ClientOrderItems.cloi_current_status
) B
ON A.cl_id = B.cl_id
WHERE ...
GROUP BY ...
This will be treated as a separate result set, so you can also filter results with a WHERE or just a GROUP BY, just like in a normal SELECT.
UPDATE:
To answer the question in your comments, when you join two tables that have a column with the same value and use
SELECT * FROM A INNER JOIN B the * will show all columns returned by the join, meaning all columns from A and all columns from B, this is why you have duplicate columns.
If you want to filter the columns returned you can specifiy which columns you want returned. So, in your case, the top SELECT * can be replaced with
SELECT A.cl_id, A.cl_name, A.number_of_orders, B.dis so, your query becomes:
SELECT A.cl_id, A.cl_name, A.number_of_orders, B.dis
FROM (
SELECT CL_Clients.cl_id,
CL_Clients].cl_name,
COUNT(*) AS number_of_orders
FROM CL_Clients,
CLOI_ClientOrderItems
WHERE CL_Clients.cl_id = CLOI_ClientOrderItems.cl_id
GROUP BY CL_Clients.cl_name,
CL_Clients.cl_id
) A
INNER JOIN (
SELECT CL_Clients.cl_id,
count(cloi_current_status) AS dis
FROM CLOI_ClientOrderItems,
CL_Clients
WHERE cloi_current_status] = '12'
AND CL_Clients.cl_id = CLOI_ClientOrderItems.cl_id
GROUP BY CL_Clients.cl_name,
CL_Clients.cl_id,
CLOI_ClientOrderItems.cloi_current_status
) B
ON A.cl_id = B.cl_id
UPDATE #2:
For your last question, you need to GROUP BY at the end of the big query and use a HAVING condtion, like this:
GROUP BY A.cl_id, A.cl_name, A.number_of_orders, B.dis
HAVING COUNT(cloi_current_status) > 100
All depends on what data you are trying to get, but you can go about it like this.
SELECT Column_x, Column_y, etc..
FROM ClL_Clients a
JOIN (select CL_Clients.cl_id,CL_Clients].cl_name,COUNT(*) AS number_of_orders
from CL_Clients,CLOI_ClientOrderItems
where CL_Clients.cl_id=CLOI_ClientOrderItems.cl_id
group by CL_Clients.cl_name,CL_Clients.cl_id) b
on a.cl_id = b.cl_id
JOIN (select CL_Clients.cl_id,count(cloi_current_status) as dis
from CLOI_ClientOrderItems,CL_Clients
where cloi_current_status]='12'
and CL_Clients.cl_id=CLOI_ClientOrderItems.cl_id
group by CL_Clients.cl_name,CL_Clients.cl_id,CLOI_ClientOrderItems.cloi_current_status) c
on a.cl_id = c.cl_id
Group by BLAH BLAH
Hope this gets you in the right direction.