ms sql subquery different where clause same tables - sql

I'm trying to build the following query:
SELECT
COUNT(dbo.[Order].OrderID) AS Orders,
SUM(dbo.OrderLine.SubTotal) + SUM(dbo.OrderLine.Shipping) - SUM(dbo.OrderLine.Discount) AS Revenue,
SUM(dbo.OrderLine.Shipping) AS Expr1,
DATEADD(dd, 0, DATEDIFF(dd, 0, dbo.[Order].PaymentDate)) AS RevenueDate,
(SUM(dbo.OrderLine.SubTotal) + SUM(dbo.OrderLine.Shipping)) / COUNT(dbo.[Order].OrderID) AS RevenuePerOrder,
SUM(dbo.OrderLine.Qty) AS Qty
FROM
dbo.[Order]
INNER JOIN dbo.OrderLine ON dbo.[Order].OrderID = dbo.OrderLine.OrderID
INNER JOIN (
SELECT SUM(dbo.OrderLine.SubTotal) + SUM(dbo.OrderLine.Shipping) - SUM(dbo.OrderLine.Discount) AS BulkRevenue
FROM dbo.OrderLine
INNER JOIN dbo.[Order] ON dbo.OrderLine.OrderID = dbo.[Order].OrderID
WHERE BulkOrder = 1) bulkrevenue
WHERE (dbo.[Order].OrderStatusID IN (2))
AND (dbo.[Order].PaymentDate >= CONVERT(DATETIME, '02/03/2014', 103))
AND (dbo.[Order].PaymentDate <= CONVERT(DATETIME, '08/03/2014', 103))
AND (dbo.[Order].WebsiteID = 2)
GROUP BY DATEADD(dd, 0, DATEDIFF(dd, 0, dbo.[Order].PaymentDate)), dbo.[Order].WebsiteID
The Sub Query/second INNER JOIN is where things fail, is this something I can do? I want to get Bulk Order Revenue as a another column in the same result set.
Hope this makes sense.
Thanks,
Michael

It looks like your are not specifying what key to join on for your second inner join.
INNER JOIN (
SELECT SUM(dbo.OrderLine.SubTotal) + SUM(dbo.OrderLine.Shipping) - SUM(dbo.OrderLine.Discount) AS BulkRevenue
FROM dbo.OrderLine
INNER JOIN dbo.[Order] ON dbo.OrderLine.OrderID = dbo.[Order].OrderID
WHERE BulkOrder = 1) bulkrevenue ON bulkrevenue.___ = table.____
This may be a case where an outer apply, or cross apply will better suit your needs (I believe your current operation of sums will display the same for every row, not sure if that is intended) see http://sqlserverplanet.com/sql-2005/cross-apply-explained

Related

How would you write this SQL query without the use of a temp table?

I am having difficulty running this query in Power Bi because it uses a temporary table. How would I write this without a temp table?
SELECT Convert(varchar,TT1.POST_DATE,110) as 'POST_DATE',
COUNT (DISTINCT TT1.TRAN_DATE) as 'NO_DAYS_ENTERED',
HP4.EMPLOYEE_CODE,
HP4.EMPLOYEE_NAME,
HP4.EMPLOYEE_NAME + ' (' + LEFT(HB6.OFFC_DESC,3) + ')' as 'EMPLOYEE_NAME_2',
TT1.OFFC,
HB6.OFFC_DESC,
HP4.GRAD_YEAR,
TB1.RANK_CODE,
TR1.RANK_DESC
into #tempG1
FROM TAT_TIME TT1
LEFT JOIN HBM_PERSNL HP4 ON TT1.TK_EMPL_UNO = HP4.EMPL_UNO
INNER JOIN TBM_PERSNL TB1 on HP4.EMPL_UNO = TB1.EMPL_UNO
INNER JOIN TBL_RANK TR1 on TB1.RANK_CODE = TR1.RANK_CODE
INNER JOIN HBL_OFFICE HB6 on HP4.OFFC = HB6.OFFC_CODE
WHERE TB1.RANK_CODE IN ('4')
AND HP4.INACTIVE = 'N'
AND TT1.POST_DATE >= DATEADD(month, -3, GETDATE())
GROUP BY TT1.POST_DATE, HP4.EMPLOYEE_CODE, HP4.GRAD_YEAR, HP4.EMPLOYEE_NAME, TT1.OFFC, TB1.RANK_CODE, TR1.RANK_DESC, HB6.OFFC_DESC
select G1.EMPLOYEE_NAME,
G1.EMPLOYEE_NAME_2,
datediff(day, min(G1.POST_DATE), max(G1.POST_DATE)) * 1.0 / nullif(count(*) - 1, 0) as 'AVG_FREQ'
from #tempG1 G1
group by G1.EMPLOYEE_NAME, G1.EMPLOYEE_NAME_2
drop table #tempG1
You need to refer query of #tempG1 as an inline view in your main SQL.
Try this -
select G1.EMPLOYEE_NAME,
G1.EMPLOYEE_NAME_2,
datediff(day, min(G1.POST_DATE), max(G1.POST_DATE)) * 1.0 / nullif(count(*) - 1, 0) as 'AVG_FREQ'
from (SELECT Convert(varchar,TT1.POST_DATE,110) as 'POST_DATE',
COUNT (DISTINCT TT1.TRAN_DATE) as 'NO_DAYS_ENTERED',
HP4.EMPLOYEE_CODE,
HP4.EMPLOYEE_NAME,
HP4.EMPLOYEE_NAME + ' (' + LEFT(HB6.OFFC_DESC,3) + ')' as 'EMPLOYEE_NAME_2',
TT1.OFFC,
HB6.OFFC_DESC,
HP4.GRAD_YEAR,
TB1.RANK_CODE,
TR1.RANK_DESC
FROM TAT_TIME TT1
LEFT JOIN HBM_PERSNL HP4 ON TT1.TK_EMPL_UNO = HP4.EMPL_UNO
INNER JOIN TBM_PERSNL TB1 on HP4.EMPL_UNO = TB1.EMPL_UNO
INNER JOIN TBL_RANK TR1 on TB1.RANK_CODE = TR1.RANK_CODE
INNER JOIN HBL_OFFICE HB6 on HP4.OFFC = HB6.OFFC_CODE
WHERE TB1.RANK_CODE IN ('4')
AND HP4.INACTIVE = 'N'
AND TT1.POST_DATE >= DATEADD(month, -3, GETDATE())
GROUP BY TT1.POST_DATE, HP4.EMPLOYEE_CODE, HP4.GRAD_YEAR, HP4.EMPLOYEE_NAME, TT1.OFFC, TB1.RANK_CODE, TR1.RANK_DESC, HB6.OFFC_DESC
) G1
group by G1.EMPLOYEE_NAME, G1.EMPLOYEE_NAME_2

SUM RESULTS OF CASE STATEMENTS

I've this query working fine. I need to have the sum of the column "piedini". Can you help me to undestand how to do? I obtain X row for each "Lunghezza" (lenght) that the query find. I'm not interested to this field but only to the sum o column "piedini" created from the CASE SUM.
SELECT
EXTRAMAG.PRS_LUNGHEZZA,SUM(RIGHEDOCUMENTI.QTAGEST) AS TAVOLI, CASE WHEN EXTRAMAG.PRS_LUNGHEZZA < '2000' THEN SUM(RIGHEDOCUMENTI.QTAGEST)*4 ELSE SUM(RIGHEDOCUMENTI.QTAGEST)*6 END AS PIEDINI
FROM dbo.TESTEDOCUMENTI
INNER JOIN dbo.ANAGRAFICACF
ON CODCLIFOR=CODCONTO
INNER JOIN dbo.RIGHEDOCUMENTI
ON PROGRESSIVO=IDTESTA AND TOTNETTORIGA <>'0' AND RIGHEDOCUMENTI.DESCRIZIONEART LIKE '%TAVOL%'
INNER JOIN dbo.EXTRAMAG
ON RIGHEDOCUMENTI.CODART=EXTRAMAG.CODART
LEFT JOIN .dbo.ANAGRAFICAAGENTI
ON CODAGENTE=CODAGENTE1
LEFT JOIN dbo.TABPAGAMENTI
ON CODPAGAMENTO = CODICE
WHERE dbo.TESTEDOCUMENTI.DOCCHIUSO = '0' AND dbo.TESTEDOCUMENTI.BLOCCATO = '0' AND dbo.TESTEDOCUMENTI.TIPODOC = 'ORC' AND TESTEDOCUMENTI.DATACONSEGNA BETWEEN DATEADD(DAY, -60, GETDATE()) AND GETDATE()
GROUP BY EXTRAMAG.PRS_LUNGHEZZA
Try the below :
select sum(PIEDINI) from (
SELECT XTRAMAG.PRS_LUNGHEZZA,SUM(RIGHEDOCUMENTI.QTAGEST) AS TAVOLI, CASE WHEN EXTRAMAG.PRS_LUNGHEZZA < '2000' THEN SUM(RIGHEDOCUMENTI.QTAGEST)*4 ELSE SUM(RIGHEDOCUMENTI.QTAGEST)*6 END AS PIEDINI
FROM dbo.TESTEDOCUMENTI
INNER JOIN dbo.ANAGRAFICACF
ON CODCLIFOR=CODCONTO
INNER JOIN dbo.RIGHEDOCUMENTI
ON PROGRESSIVO=IDTESTA AND TOTNETTORIGA <>'0' AND RIGHEDOCUMENTI.DESCRIZIONEART LIKE '%TAVOL%'
INNER JOIN dbo.EXTRAMAG
ON RIGHEDOCUMENTI.CODART=EXTRAMAG.CODART
LEFT JOIN .dbo.ANAGRAFICAAGENTI
ON CODAGENTE=CODAGENTE1
LEFT JOIN dbo.TABPAGAMENTI
ON CODPAGAMENTO = CODICE
WHERE dbo.TESTEDOCUMENTI.DOCCHIUSO = '0' AND dbo.TESTEDOCUMENTI.BLOCCATO = '0' AND dbo.TESTEDOCUMENTI.TIPODOC = 'ORC' AND TESTEDOCUMENTI.DATACONSEGNA BETWEEN DATEADD(DAY, -60, GETDATE()) AND GETDATE()
GROUP BY EXTRAMAG.PRS_LUNGHEZZA
)t

SELECT Agents Who Have Not Been Evaluated (by week)

Trying to pull list of agents that have not been Evaluated (Scored) in the past week. I'm getting the Agent_Name, but when checking list of Evaluations, their names are appearing in the Evaluation list.
select agent.firstname + ' ' + agent.lastname Agent_Name
from dbo.agent agent
left outer join dbo.crr crr
on agent.id = crr.agentfk
left outer join dbo.evaluation eval
on crr.id = eval.crrfk
where eval.crrfk is null
and crr.localtime >= Dateadd(Day, Datediff(Day, 0, Dateadd(D, -7, Current_Timestamp)), 0);
You need to move the condition on crr to the on clause:
select agent.firstname + ' ' + agent.lastname Agent_Name
from dbo.agent agent left outer join
dbo.crr crr
on agent.id = crr.agentfk and
crr.localtime >= Dateadd(Day, Datediff(Day, 0, Dateadd(D, -7, Current_Timestamp)), 0) left outer join
dbo.evaluation eval
on crr.id = eval.crrfk
where eval.crrfk is null ;
I'm not sure why you need the evaluation table, if the data is in crr. I mean, this should do the same thing (assuming you are using the right date):
select (a.firstname + ' ' + a.lastname) as Agent_Name
from dbo.agent a left outer join
dbo.crr
on a.id = crr.agentfk and
crr.localtime >= Dateadd(Day, Datediff(Day, 0, Dateadd(D, -7, Current_Timestamp)), 0)
where crr.id is null ;

My query only returns 1 row. I expect more

I am trying to sum values in a result set on a table with 2 joins.
I have a table called Limit.
A Limit has many Allocations.
A Limit also has many Extensions.
Both Allocations and Extensions have one Entity.
When I specify the Limit with an Oid in my where clause, I get one record returned. Even though the Limit has 9 Allocations.
If the Limit has 9 Allocations and 0 Extensions, I get still get 1 returned.
Even thought the Limit has Zero Extensions, I still expect the 9 Allocations.
I hope this makes sense. Here is my Updated query:
-----I updated my query with this. I am now getting the correct amount of records for the given limit. I get 9 records:------
select
convert(varchar(100), l.oid) AS keyfield,
l.oid as Limit,
la.SourceEntity as SourceEntity,
SUM(ISNULL(la.ARLimit, 0)) + SUM(ISNULL(le.ARLimit, 0)) AS ARLimit,
SUM(ISNULL(la.MTMLimit, 0)) + SUM(ISNULL(le.MTMLimit, 0)) AS MTMLimit,
SUM(ISNULL(la.Volume, 0)) + SUM(ISNULL(le.Volume, 0)) AS Volume,
SUM(ISNULL(la.MaxTenor, 0)) + SUM(ISNULL(le.MaxTenor, 0)) AS MaxTenor
from limit l
left join limitallocation la
on l.oid = la.limit
left join limitextension le
on l.oid = le.limit
where l.Oid = '893de7ad-0ed2-462f-8bac-a26718b3e798'
GROUP BY l.Oid, la.SourceEntity
By using join you are expecting a result on the joined table, if there is no result then it will fail.
If you still wand the data you have regardless if there is a matching record on the table your joining, you need to use left join.
select
convert(varchar(100), l.oid) AS keyfield,
l.oid as Limit,
se.Oid as SourceEntity,
SUM(ISNULL(la.ARLimit, 0)) + SUM(ISNULL(le.ARLimit, 0)) AS ARLimit,
SUM(ISNULL(la.MTMLimit, 0)) + SUM(ISNULL(le.MTMLimit, 0)) AS MTMLimit,
SUM(ISNULL(la.Volume, 0)) + SUM(ISNULL(le.Volume, 0)) AS Volume,
SUM(ISNULL(la.MaxTenor, 0)) + SUM(ISNULL(le.MaxTenor, 0)) AS MaxTenor
from limit l
join limitallocation la
on l.oid = la.limit
left join limitextension le
on l.oid = le.limit
join
dbo.SourceEntity as se
on la.SourceEntity = se.oid
and le.SourceEntity = se.Oid
where l.Oid = '893de7ad-0ed2-462f-8bac-a26718b3e798'
GROUP BY l.Oid, se.Oid
You need to use Left Join on the tables, as you have not specified type of the join inner join will be applied because of which only matching rows of all the tables in the Join will be displayed.
The table from which you want to get the records in the join no matter if the record exists in the the other table should be used as Left table.
In your case if you want to get all the data in Limit table with Oid = '893de7ad-0ed2-462f-8bac-a26718b3e798' you should use this table on the Left in Join after forming the result of this if you want to get all the data of limitallocation no matter whether the data exists in limitextension table then limitallocation should be used on Left side.
Your query will be
select convert ( VARCHAR ( 100), L.OID) as KEYFIELD
,L.OID as limit
,SE.OID as SOURCEENTITY
,sum ( ISNULL ( LA.ARLIMIT, 0)) + sum ( ISNULL ( LE.ARLIMIT, 0)) as ARLIMIT
,sum ( ISNULL ( LA.MTMLIMIT, 0)) + sum ( ISNULL ( LE.MTMLIMIT, 0)) as MTMLIMIT
,sum ( ISNULL ( LA.VOLUME, 0)) + sum ( ISNULL ( LE.VOLUME, 0)) as VOLUME
,sum ( ISNULL ( LA.MAXTENOR, 0)) + sum ( ISNULL ( LE.MAXTENOR, 0)) as MAXTENOR
from limit L
left join LIMITALLOCATION LA on L.OID = LA.limit
left join LIMITEXTENSION LE on L.OID = LE.limit
left join DBO.SOURCEENTITY as se
on la.SourceEntity = se.oid
and le.SourceEntity = se.Oid
where l.Oid = '893de7ad-0ed2-462f-8bac-a26718b3e798'
GROUP BY l.Oid, se.Oid

grouping monthly with joins

I a having issues grouping the query below into monthly aggregate.
Table is cross joined with a table to pick up the rate and inner joined with another that contains just dates to show nulls for dates where data doesnt exist in the table (Client Request)
It works fine with the daily grouping which is below. Please how can I group it monthly.
Select * from(select [Letter_Date] [Date],Council
SUM([Total_Corr])*[Rate][Total]
FROM Correspondence
cross join
Input_Variable_Price
where [Revenue_Name] = 'Correspondence'
group by [Letter_Date],Council)AS ED
RIGHT JOIN
(Select '21'[No],b_date,[Revenue_Name][Report],[Unit],[Rate]
From Blank_dates
cross join
Input_Variable_Price
where [Revenue_Name] = 'Correspondence') AS BD
ON ED.Date = BD.[b_date]
Cheers
I would use the following: add in any other aggregations you need to the SELECT, and whatever items in the GROUP BY that you require.
Select DATEADD(month, DATEDIFF(month, 0, [Date]), 0) AS StartOfMonth, SUM(Total)
from
(
select [Letter_Date] [Date],Council,
SUM([Total_Corr])*[Rate] [Total]
FROM
Correspondence
cross join
Input_Variable_Price
where [Revenue_Name] = 'Correspondence'
group by [Letter_Date],Council
)AS ED
RIGHT JOIN
(
Select
'21'[No],
b_date,
[Revenue_Name][Report],
[Unit],
[Rate]
From
Blank_dates
cross join
Input_Variable_Price
where [Revenue_Name] = 'Correspondence'
) AS BD ON
ED.Date = BD.[b_date]
GROUP BY DATEADD(month, DATEDIFF(month, 0, [Date]), 0)