Error in CTE: The multi part identifier could not be bound - sql

Table Structure:
dbo.PS_Margin
2 Columns
[Project Profit by Person %], [Emp or Vendor ID]
Error Messages:
Invalid object name 'dbo.PS_Margin'
(Solved) The multi part identifier could not be bound "PS_Margin.Emp or Vendor ID
Issues/ Goals:
Error messages above
Possible need to add aliases (or fix current aliases) to column names with spaces and special characters although I don't know how to do this
WITH Profit_Score_CTE ( [Emp or Vendor ID], [Project Profit by Person %], [Profit Score] ) AS (
SELECT ps.[Emp or Vendor ID], [Profit Score],
CASE
WHEN ps.[Project Profit by Person %] > .4 THEN 1
WHEN ps.[Project Profit by Person %] > .2 THEN 3
WHEN ps.[Project Profit by Person %] > .1 THEN 5
WHEN ps.[Project Profit by Person %] > .05 THEN 8
ELSE 13 END
AS [Profit Score]
FROM dbo.PS_Margin ps )
SELECT PS_Emp.[Employee Name], PS_Emp.[USID], [Profit Score]*0.3 AS [Final Score]
FROM dbo.PS_Emp LEFT OUTER JOIN Profit_Score_CTE ps
ON PS_Emp.[USID] = ps.[Emp or Vendor ID]

Perhaps you intend:
SELECT PS_Emp.[Employee Name], PS_Emp.[USID], [Profit Score]*0.3 AS [Final Score]
FROM dbo.PS_Emp LEFT OUTER JOIN
Profit_Score_CTE ps
ON PS_Emp.[USID] = ps.[Emp or Vendor ID]
You have defined the CTE but you are not using it.

Related

Why does my record count increase as my denominator for a division performed in a nested query increases?

In my query I'm trying to calculate the total overtime worked by employees by dividing basic salary by 173(hours in a month) which gives me the hourly rate then dividing the total overtime amount of employee by the hourly rate. To my surprise the record count increases as the number of hours in a month increases, should it not decrease?
Here's my script:
select 'Employees that worked more overtime' [CAAT],*
from ( select H.[Month]
,H.[Employee Code]
,H.[Department]
,H.[Job title]
,H.[Surname]
,H.[Full Names]
,H.[Basic Salary]
,R.[Overtime]
,H.[Hourly Rate]
,round(R.[Overtime] / H.[Hourly Rate],2) [Overtime Hours]
from (select [Month]
,[Employee Code]
,Department
,[Job title]
,[Surname]
,[Full Names]
,nullif(convert(money,[Amount]),0.00) [Basic Salary]
,nullif(round(convert(money,[Amount]) / 173,2),0.00) [Hourly Rate]
from [Salary DB]
where [Field Desc] = 'ED01-Basic Salary') H
left join
(select [Month]
,[Employee Code]
,nullif(sum(convert(money,[Amount])),0.00) [Overtime]
from [Salary DB]
where [Field Desc] in ('ED02-O/Time 1.5','ED02-O/Time 2.0','ED42-Sunday Pay')
group by [Month]
,[Employee Code]) R
on H.[Employee Code] = R.[Employee Code]
and H.[Month] = R.[Month]) [Data]
where [Overtime Hours] > '40'
Order by [Employee Code], [Month] Desc

Calculate AVG in SQL Select statement when some values are NULL

I have struggled to find a solution to this problem, so any help would be hugely appreciated.
I have two tables, lets call one table_a and one table_b, representing two possible sources of customer orders. They both contain a field called "customer_number" which I am using to outer join table_b to table_a. I am then calculating an average customer order size given the two tables.
Where i struggle is where a customer has an entry in either table, but not in both. Then my average calc returns NULL.
Table_a:
Customer Number
Total Online Orders
123456789
1350
987654321
650
Table_b:
Customer Number
Total InStore Orders
123456789
350
So basically the second customer does not have an entry in table_b.
My code as follows:
select distinct
a.[customer number],
a.[Total Online Orders],
b.[Total InStore Orders],
coalesce(a.[Total Online Orders] + b.[Total InStore Orders]) / 2 as [Average Order Size]
from table_a a
full outer join table_b b on a.[customer number]=b.[customer number]
Results table:
Customer Number
Total Online Orders
Total InStore Orders
Average Order Size
123456789
1350
350
850
987654321
650
NULL
NULL
I basically want the results table to show 650 for customer 987654321. Any ideas what I am doing wrong?
thanks!
You can use the brute force method:
( coalesce(a.[Total Online Orders], 0) + coalesce(b.[Total InStore Orders], 0)) /
nullif(case when a.[Total Online Orders] is not null then 1 else 0 end +
case when b.[Total InStore Orders] is not null then 1 else 0 end, 0)
)
) as [Average Order Size]
Use COALESCE() for the values of the 2 columns twice:
(
coalesce(a.[Total Online Orders], b.[Total InStore Orders]) +
coalesce(b.[Total InStore Orders], a.[Total Online Orders])
) / 2 as [Average Order Size]
Consider UNION as well, which handles a few other cases too, especially where customer number isn't necessarily unique in each table:
WITH cte (xtype, [customer number], order_amt) AS (
select 1 AS xtype, [customer number], [Total Online Orders] FROM table_a UNION ALL
select 2 AS xtype, [customer number], [Total InStore Orders] FROM table_b
)
SELECT [customer number]
, SUM(CASE WHEN xtype = 1 THEN order_amt ELSE 0 END) AS [Total Online Orders]
, SUM(CASE WHEN xtype = 2 THEN order_amt ELSE 0 END) AS [Total InStore Orders]
, AVG(order_amt) AS [Average Order Size]
FROM cte
GROUP BY [customer number]
ORDER BY [customer number]
;

Subtract column data from two unrelated tables

This is the database diagram I want to determine the blood that's remaining in each bank this achieved by subtracting [Amount Accepted] from [Amount Donated]
I have tried to make selections of blood drawn into banks and blood withdrawn from banks but my problem is I can't subtract the two columns [blood drawn] and [blood withdrawn] because they are in tables which are not related
You can try like following.
SELECT *, [blood drawn(ml)]-[blood withdrawn(ml)]
FROM
(
<YOUR QUERY1>
)A
INNER JOIN
(
<YOUR QUERY2>
)B
ON A.[Blood Bank Name]= B.[Blood Bank Name]
Wrap both Selects in Derived Tables or Common Table Expressions and join them, e.g.
with donated as
( select ...
)
, accepted as
( select ...
)
select ...
from donated as a
join accepted as a
on a.[blood bank name] = d..[blood bank name]
Note the '-' before [Amount Accepted] is the key.
SELECT x.[Blood Bank Name], SUM(x.[Net Amount])
FROM
(
SELECT [Blood Bank Name], [Amount Donated] AS [Net Amount]
FROM [Donation Record]
UNION ALL
SELECT [Blood Bank Name], -[Amount Accepted] AS [Net Amount]
FROM [Transfusion Record]
) x
GROUP BY x.[Blood Bank Name]

Script help - count , total and avg

I have the following script, trying to count how many distinct customers are there , how many distinct orders , what is total of all orders under £15 and its's avg, total of orders above £20 and it's avg.
with consignments as
(select
[Sell-to Customer No_],
[Convert-to Document No_],
ic.[Shipping Agent Service Code],
[Pick Completed DateTime] as [Shipped DateTime],
ROUND((ic.[Amount Including VAT] + ic.Postage + ic.[Gift Wrap Price] +
ic.[Handling Fee] + ic.[Personalisation Fee]),2) as [Document Amount]
from dbo.[Temp$Consignment] ic inner join [dbo].
[Temp$Order] oh
on ic.[Owner Header GuID]=oh.[Order Guid]
where ic.[Shipping Agent Service Code]='secstan' and ic.[Pick Completed
DateTime] >= '2016-11-01T00:00:00.000' AND
ic.[Pick Completed DateTime] <= '2016-11-30T23:59:55.000' ),summary as
(select *,CASE WHEN [Document Amount] > 15 THEN 1 ELSE 0 END as 'Over15'
from consignments )select * from summary
I have working script like below, but as I am new to sql I am bit confused how to convert above script to below.
select amountclass,[Shipping Agent Service Code],
count(distinct [Sell-to Customer No_]) as Total_customers,
count(*) as Total_orders,
sum([Amount]) as total_revenue,
avg([Amount] * 1.0) as AOV
from
(
select [Sell-to Customer No_], oh.[Original Order No_], [Amount],ic.
[Shipping Agent Service Code],
case when [Amount] <= 20 then 'Under_20'
else 'Over_20'
end as amountclass
from [TBW_BI].[dbo].[Temp$Order] oh INNER JOIN [TBW_BI].[dbo].
[Temp$Consignment] IC
ON IC.[Owner Header GuID]=OH.[Order Guid]
where[order date] >= '2016-09-01' AND
[order date] <= '2016-09-30' AND [COUNTRY]='UNITED KINGDOM' and
[document type] like 'ord%' and ic.[Shipping Agent Service
Code]='secstan'
) dt
group by amountclass,[Shipping Agent Service Code]
order by amountclass,[Shipping Agent Service Code]
It looks like you have a query with a 2 Common Table Expressions (CTE) and you want to convert the CTE to a derived table. First, we can eliminate one of the CTEs.
summary as
(select *,CASE WHEN [Document Amount] > 15 THEN 1 ELSE 0 END as 'Over15'
from consignments )
select * from summary
The CTE for summary is unnecessary. We can convert that code to this:
select *,CASE WHEN [Document Amount] > 15 THEN 1 ELSE 0 END as 'Over15'
from consignments
Now, instead of using the consignments CTE; we can copy the sql code within it to create a derived table.
select *,CASE WHEN [Document Amount] > 15 THEN 1 ELSE 0 END as 'Over15'
from (
select [Sell-to Customer No_],
[Convert-to Document No_],
ic.[Shipping Agent Service Code],
[Pick Completed DateTime] as [Shipped DateTime],
ROUND((ic.[Amount Including VAT] + ic.Postage + ic.[Gift Wrap Price] +
ic.[Handling Fee] + ic.[Personalisation Fee]),2) as [Document Amount]
from dbo.[Temp$Consignment] ic
inner join [dbo].[Temp$Order] oh on ic.[Owner Header GuID]=oh.[Order Guid]
where ic.[Shipping Agent Service Code]='secstan'
and ic.[Pick Completed
DateTime] >= '2016-11-01T00:00:00.000'
AND
ic.[Pick Completed DateTime] <= '2016-11-30T23:59:55.000' ) as t

MDX as Calculated Member in SSAS Cube

I have a FactBudget per sales region with fields [Budget SalesRegion] and [Sales Region]. In the dimension DimCustomer I have the fields [Sales Region] and [Customer Type].
The relation between FactBudget and DimCustomer is defined only on the [Sales Region].
I have a rather simple mdx statement that filters the [Sales Region] of the DimCustomer for a certain [Customer Type]. With the returned [Sales Region] I select the correspondent [Budget SalesRegion]:
SELECT
(
FILTER(
[Kunde].[Sales Region].members
,[Kunde].[Customer Type].CURRENTMEMBER
=[Kunde].[Customer Type].[All].[Direct Sales]
)
,[Measures].[Budget SalesRegion]
) ON 0,
[Kunde].[Customer Type].[All].[Direct Sales] ON 1
FROM [BI_DWH];
How can I translate this statement into an Calculated Member in the SSAS cube so that the selected [Customer Type] in a slicer filters the statement accordingly?
This:
SELECT
(
FILTER(
[Kunde].[Sales Region].members
,[Kunde].[Customer Type].CURRENTMEMBER
=[Kunde].[Customer Type].[All].[Direct Sales]
)
,[Measures].[Budget SalesRegion]
) ON 0,
[Kunde].[Customer Type].[All].[Direct Sales] ON 1
FROM [BI_DWH];
Is the same as this:
SELECT
[Measures].[Budget SalesRegion] ON 0,
[Kunde].[Customer Type].[All].[Direct Sales] ON 1
FROM [BI_DWH];
Or if you want to use the slicer axis:
SELECT
[Measures].[Budget SalesRegion] ON 0
FROM [BI_DWH]
WHERE [Kunde].[Customer Type].[All].[Direct Sales];
Now it is simplified I do not understand what you question is?