I am trying to inner join 2 temp tables
I know this can be done, I have done this before but i completely forgot how to do it
Please advise meBelow is the query that I try to execute
select tmp1.*, tmp2.cnt from
(
select
1 as ClassificationType,
tblMatches.IdGame,
tblMatches.IdPlayer,
sum(Score) as Score, sum(Points) as Points, sum(OpponentScore) as OpponentScore,
count(ID) as MatchesCount, count(distinct IdCompetition) as CompetitionsCount
from
tblMatches
group by IdPlayer, IdGame
) as tmp1
inner join (select IdWinner, count(IdWinner) as cnt from tblCompetitions where IdWinner = tmp1.IdPlayer) as tmp2
on tmp2.IdWinner = tmp1.IdPlayer
This will fail with
I think I am not allowed to use tmp1 in the subquery that create tmp2
Msg 4104, Level 16, State 1, Line 17
The multi-part identifier
"tmp1.IdPlayer" could not be bound.
You are not trying to join two temp tables, but two derived tables.
You cannot access the inner data of one derived table in outside of it unless it's in the SELECT clause.
Try the following:
select tmp1.*, tmp2.cnt from
(
select
1 as ClassificationType,
tblMatches.IdGame,
tblMatches.IdPlayer,
sum(Score) as Score, sum(Points) as Points, sum(OpponentScore) as OpponentScore,
count(ID) as MatchesCount, count(distinct IdCompetition) as CompetitionsCount
from
tblMatches
group by IdPlayer, IdGame
) as tmp1
inner join (select IdWinner, count(IdWinner) as cnt from tblCompetitions GROUP BY IdWinner) as tmp2
on tmp2.IdWinner = tmp1.IdPlayer
select
1 as ClassificationType,
tmp1.IdGame,
tmp1.IdPlayer,
sum(tmp1.Score) as Score,
sum(tmp1.Points) as Points,
sum(tmp1.OpponentScore) as OpponentScore,
count(tmp1.ID) as MatchesCount,
count(distinct tmp1.IdCompetition) as CompetitionsCount,
count(tmp2.IdWinner) as cnt
from
tblMatches tmp1
inner join
tblCompetitions tmp2
on tmp2.IdWinner = tmp1.IdPlayer
group by
tmp1.IdPlayer,
tmp1.IdGame
The where clause in tmp2 duplicates the join condition:
inner join (select IdWinner, count(IdWinner) as cnt
from tblCompetitions
where IdWinner = tmp1.IdPlayer) as tmp2
on tmp2.IdWinner = tmp1.IdPlayer
Just remove the where clause. In addition, like Astander noted in his now deleted post, the second query needs a group by too:
inner join (select IdWinner, count(IdWinner) as cnt
from tblCompetitions
group by IdWinner) as tmp2
on tmp2.IdWinner = tmp1.IdPlayer
The reason you can't reference the outer query from a subquery is that this would make the right part of the join depend on the left part of the join.
You shouldn't actually need the second subquery. What about this?
SELECT tmp1.ClassificationType, tmp1.IdGame, tmp1.IdPlayer,
COUNT(tblCompletions.IdWinner) as cnt FROM
(
SELECT
1 as ClassificationType,
tblMatches.IdGame,
tblMatches.IdPlayer,
sum(Score) as Score, sum(Points) as Points, sum(OpponentScore) as OpponentScore,
count(ID) as MatchesCount, count(distinct IdCompetition) as CompetitionsCount
FROM
tblMatches
GROUP BY IdPlayer, IdGame
) as tmp1
INNER JOIN tblCompletions ON tmp1.IdPlayer = tblCompletions.IdWinner
GROUP BY tmp1.ClassificationType, tmp1.IdGame, tmp1.IdPlayer
Related
I'm after some help please i'm new to SQL, can you help me join these to queries below I want all the data from the first query to be displayed and only the information that matches to be showed on the second query.
Part and subkey1 is the join
Thank you.
SELECT RHeads.[Document],
RLines.Part,
RHeads.Supp,
RHeads.DATETIME,
RLines.Unit,
RLines.CQty,
RHeads.POrder,
RHeads.Corder,
RHeads.Branch
FROM RLines
RIGHT OUTER JOIN RHeads ON RLines.[Document] = RHeads.[Document]
WHERE (RHeads.DATETIME >= DATEADD(MONTH, - 3, GETDATE()))
AND (RHeads.Corder = '02022076')
ORDER BY RHeads.DATETIME DESC;
SELECT Mvpr.Prefix,
Mvpr.SubKey1,
Mvpr.SubKey2,
Mvpr.A12
FROM Mvpr
INNER JOIN vwProduct ON Mvpr.SubKey1 = vwProduct.KeyCode
WHERE (Mvpr.Prefix = 'c');
Just stick both of these SQL statements into their own subquery (using parantheses) and give each subquery an alias so we can refer to it's result set in the main query:
SELECT
t1.*,
t2.*
FROM
(
SELECT RHeads.[Document],
RLines.Part,
RHeads.Supp,
RHeads.DATETIME,
RLines.Unit,
RLines.CQty,
RHeads.POrder,
RHeads.Corder,
RHeads.Branch
FROM RLines
RIGHT OUTER JOIN RHeads ON RLines.[Document] = RHeads.[Document]
WHERE (RHeads.DATETIME >= DATEADD(MONTH, - 3, GETDATE()))
AND (RHeads.Corder = '02022076')
) t1
LEFT OUTER JOIN
(
SELECT Mvpr.Prefix,
Mvpr.SubKey1,
Mvpr.SubKey2,
Mvpr.A12
FROM Mvpr
INNER JOIN vwProduct ON Mvpr.SubKey1 = vwProduct.KeyCode
WHERE (Mvpr.Prefix = 'c')
) t2 ON t1.Part = t2.SubKey1
ORDER BY t1.DATETIME DESC;
We're using a LEFT OUTER JOIN to get all of the records from t1 (first query) and only those records that match from t2 (second query).
Also I have moved the ORDER BY clause to the main query as you can't ORDER inside of a subquery (and even if you were allowed to, the ordering would be lost after the join so it would be superfluous).
Since you aren't doing any aggregating here, you could probably rewrite this without the subquery too.
I've made some assumptions about your data, but perhaps something like:
SELECT RHeads.[Document],
RLines.Part,
RHeads.Supp,
RHeads.DATETIME,
RLines.Unit,
RLines.CQty,
RHeads.POrder,
RHeads.Corder,
RHeads.Branch,
Mvpr.Prefix,
Mvpr.SubKey1,
Mvpr.SubKey2,
Mvpr.A12
FROM RHeads
LEFT OUTER JOIN RLines
ON RLines.[Document] = RHeads.[Document]
LEFT OUTER JOIN vwProduct
ON Mvpr.SubKey1 = vwProduct.KeyCode
LEFT OUTER JOIN Mvpr
ON vwProduct.KeyCode = Mvpr.Subkey1
AND Mvpr.Prefix = 'c'
WHERE
RHeads.DATETIME >= DATEADD(MONTH, - 3, GETDATE())
AND RHeads.Corder = '02022076'
If you want to maintain the granularity of the 1st query put them in CTEs and check existence:
;WITH Q1 AS(
SELECT RHeads.[Document],
RLines.Part,
RHeads.Supp,
RHeads.DATETIME,
RLines.Unit,
RLines.CQty,
RHeads.POrder,
RHeads.Corder,
RHeads.Branch
FROM RLines
RIGHT OUTER JOIN RHeads ON RLines.[Document] = RHeads.[Document]
WHERE (RHeads.DATETIME >= DATEADD(MONTH, - 3, GETDATE()))
AND (RHeads.Corder = '02022076')
), Q2 AS (
SELECT Mvpr.Prefix,
Mvpr.SubKey1,
Mvpr.SubKey2,
Mvpr.A12
FROM Mvpr
INNER JOIN vwProduct ON Mvpr.SubKey1 = vwProduct.KeyCode
WHERE (Mvpr.Prefix = 'c')
)
SELECT q1.*
FROM Q1 q1
WHERE EXISTS(
SELECT *
FROM Q2 q2
WHERE q1.Part = q2.SubKey1
)
ORDER BY q1.DATETIME DESC
SELECT DISTINCT(t1.Ticker),t2.SecurityID,t2.ClosePrice,t2.QuoteDateTime FROM [Hub].[SecurityMaster].[SecurityMasterDetails] as t1
INNER JOIN [Hub].[SecurityMaster].[SecurityPrices] as t2
ON t2.SecurityID =t1.SecurityID
WHERE t2.QuoteDateTime IN (SELECT max(QuoteDateTime) FROM [Hub].[SecurityMaster].[SecurityPrices]) AND t1.SecurityTypeName = 'REIT'
I get an output with no data. The subquery doesn't run along with the other filter in the WHERE clause. I am not sure what I am doing wrong. Can somebody please help!
If you are trying to get the lastest row from SecurityPrices for each Ticker, one option is to use cross apply():
select --distinct /* distinct not needed if `Ticker` is unique on `smd`
smd.Ticker
, sp.SecurityID
, sp.ClosePrice
, sp.QuoteDateTime
from [Hub].[SecurityMaster].[SecurityMasterDetails] as smd
cross apply (
select top 1
i.SecurityID
, i.ClosePrice
, i.QuoteDateTime
from [Hub].[SecurityMaster].[SecurityPrices] i
where i.SecurityID = smd.SecurityID
order by i.QuoteDateTime desc
) as sp
where SecurityTypeName = 'REIT' /* which table does this column belong to? */
I think your query would be
SELECT DISTINCT TOP 1 WITH TIES
t1.Ticker,
t2.SecurityID,
t2.ClosePrice,
t2.QuoteDateTime
FROM [Hub].[SecurityMaster].[SecurityMasterDetails] as t1
INNER JOIN [Hub].[SecurityMaster].[SecurityPrices] as t2 ON t2.SecurityID =t1.SecurityID
WHERE SecurityTypeName = 'REIT'
ORDER BY t2.QuoteDateTime DESC
You aren't getting results because the max(QuoteDateTime) record doesn't have SecurityTypeName = 'REIT'. I think you want the max(QuoteDateTime) for this SecurityTypeName, so this can be done with an INNER JOIN.
SELECT DISTINCT
(t1.Ticker),
t2.SecurityID,
t2.ClosePrice,
t2.QuoteDateTime
FROM [Hub].[SecurityMaster].[SecurityMasterDetails] as t1
INNER JOIN [Hub].[SecurityMaster].[SecurityPrices] as t2
ON t2.SecurityID =t1.SecurityID
INNER JOIN
(SELECT max(QuoteDateTime) DT FROM [Hub].[SecurityMaster].[SecurityPrices]) P on P.DT = t2.QuoteDateTime
WHERE SecurityTypeName = 'REIT'
EDIT
Your data doesn't have what you think it does, I suspect. Here is how you can check...
--Find the SecurityID that matches the max date
SELECT
SecurityID ,
max(QuoteDateTime) DT
FROM [Hub].[SecurityMaster].[SecurityPrices]
GROUP BY SecurityID
--I'm betting this ID isn't in your SecurityMasterDetails where the Type is REIT
SELECT DISTINCT
SecurityID
FROM SecurityMasterDetails
WHERE SecurityTypeName = 'REIT'
Since the SecurityID returned in the first query isn't in the second query result set, you are going to get NULL results.
I am trying to rewrite legacy join syntax with new standards.
SELECT count(*)
FROM es_dbo.tablTypes t
,es_dbo.tablReg r
,es_dbo.tabl_PRGandCLI p
WHERE t.ClientType *= r.ClientType
AND p.ID IN (
SELECT DISTINCT ClientID
FROM esinet_dbo.tablReG
)
AND t.ClientType IN (#intClientType)
Here is what I am trying.
SELECT count(*)
FROM es_dbo.tablTypes t
LEFT JOIN es_dbo.tablReg r ON t.ClientType = r.ClientType
LEFT JOIN es_dbo.tabl_PRGandCLI p ON p.ID IN (
SELECT DISTINCT ClientID
FROM es_dbo.tablReG
)
I am getting same no of records whether I use LEFT JOIN or INNER JOIN in 2nd part of query. Can anyone explain
Try the following:
SELECT count(*)
FROM es_dbo.tablTypes t
left join es_dbo.tablReg r on t.ClientType = r.ClientType
WHERE t.ClientType IN (#intClientType)
EXISTS (SELECT 1 FROM esinet_dbo.tablReG p WHERE r.ClientID = p.ID)
1) I assumed #intClientType is a scalar value, so no need for IN
2) removed DISTINCT and subquery as you check for existence. EXISTS should be faster as it involves finding the first element, rather than doing some sorting for DISTINCT.
3) *= was replaced with LEFT JOIN, based on discussion from here.
It is neither inner join nor left join according to query it seems like cross join so you can use following query:
SELECT count(*)
FROM es_dbo.tablTypes t
LEFT JOIN es_dbo.tablReg r ON t.ClientType = r.ClientType,
es_dbo.tabl_PRGandCLI p WHERE p.ID IN (
SELECT DISTINCT ClientID
FROM es_dbo.tablReG
)
I always look for the solution but today I surrender so please I need help.
I am using two 'inner join' because I need to get the sum of balances from two tables, but the command 'inner join ' doubles the valor when I use sum(column 1, column 2), while that when I use sum(Column 1) everything is ok.
For example:
this query work very well, but I also have to query from other table called casilleros.
select datos_usuarios.id_cliente,
datos_usuarios.nombre ,
sum(membresia.saldo)
from datos_usuarios
inner join membresiaondatos_usuarios.id_cliente=membresia.id_socio
where saldo>0
group by datos_usuarios.id_cliente, datos_usuarios.nombre
I had tried many thing for example
select datos_usuarios.id_cliente,
datos_usuarios.nombre,
sum(membresia.saldo+casilleros.saldo)
from datos_usuarios
inner join membresia on datos_usuarios.id_cliente=membresia.id_socio
inner join casilleros on datos_usuarios.id_cliente=casilleros.id_socio
group by datos_usuarios.id_cliente, datos_usuarios.nombre
But the result is wrong.
I tried with 'union all' but honestly It is not that I need.Because I need only one result of balance per client
select t0.id_cliente,
t0.nombre,
cast(sum(t1.saldo) + sum(t2.saldo) as decimal (10,2)),
from datos_usuarios t0
inner join membresia t1 on t0.id_cliente=t1.id_socio
inner join casilleros t2 on t0.id_cliente=t2.id_socio
group by t0.id_cliente, t0.nombre
UNION ALL is probably what you really want. But you want it as a derived table. Then do the sum in the outer query.
Select a.id_cliente, a.nombre, sum(a.saldo)
From
(select datos_usuarios.id_cliente, datos_usuarios.nombre, membresia.saldo from
datos_usuarios
inner join membresia on datos_usuarios.id_cliente=membresia.id_socio
inner join casilleros on datos_usuarios.id_cliente=casilleros.id_socio
UNion all
select datos_usuarios.id_cliente, datos_usuarios.nombre, casilleros.saldo from
datos_usuarios
inner join casilleros on datos_usuarios.id_cliente=casilleros.id_socio
) a
group by a.id_cliente, a.nombre
I think you want to get this query
;WITH mc AS (
SELECT saldo, id_socio
FROM membresia
UNION
SELECT saldo, id_socio
FROM casilleros
)
SELECT
datos_usuarios.id_cliente,
datos_usuarios.nombre,
sum(mc.saldo)
FROM datos_usuarios
JOIN mc ON mc.id_socio = datos_usuarios.id_cliente
GROUP BY datos_usuarios.id_cliente, datos_usuarios.nombre
We union two tables with the same structure in one pseudo table mc (using CTE) and then join our new table with table datos_usuarios.
I want to count the total number of order detail rows over all orders a customer has ever had.
This is my query
SELECT SUM(
(SELECT count(*)
FROM dbo.Order_Details
WHERE dbo.Order_Details.OrderID = dbo.Orders.OrderID))
FROM dbo.Orders
WHERE dbo.Orders.CustomerID = "123"
SQL Server is giving me an error "Cannot perform an aggregate function on an expression containing an aggregate or a subquery."
Any help with this would be appreciated.
SELECT COUNT(*)
FROM Orders
INNER JOIN Order_Details ON Orders.OrderID = Order_Details.OrderID
WHERE Orders.CustomerID = "123"
Shouldn't it just be:
SELECT count(*) FROM dbo.Order_Details, dbo.Orders
WHERE dbo.Order_Details.OrderID = dbo.Orders.OrderID
AND dbo.Orders.CustomerID = "123"
You don't need the sum() since the count(*) is already going to give you the total.
SELECT (SELECT count(*)
FROM dbo.Order_Details
WHERE dbo.Order_Details.OrderID = dbo.Orders.OrderID)
FROM dbo.Orders
WHERE dbo.Orders.CustomerID = "123"
The Count(*) is doing the summation for you. Just remove the SUM aggregate from your expression.
I should think something like the following should do what you want:
select count(1) from dbo.order_details d
join dbo.orders o on d.OrderId=o.OrderId
where dbo.orders.CustomerID="123"
The following assumes you have a column in the Order_Details table called OrderDetailID. If not, just substitute for the unique identifier for the order detail record.
SELECT COUNT(DISTINCT OD.OrderDetailID)
FROM Orders O
LEFT JOIN Order_Details OD on (OD.OrderId = O.OrderId)
WHERE O.CustomerID = "123"