Search 'AS' alias in SQL Server - sql

I have a sql query that pulls the customers full name from the customers table based on the customer ID in the sales table and binds the info to an asp.net listview. I now want to search the records by the customers full name. I used the query below but it keeps telling me that the column "Fullname" is an invalid column name. How do I go about modifying this query to work?
SELECT
tbl_Sales.SaleID, tbl_Sales.CustomerID,
(SELECT Firstname + ' ' + Lastname
FROM tbl_Customers
WHERE CustomerID = tbl_Sales.CustomerID) AS CustomerName,
tbl_Sales.Price
FROM
tbl_Sales
WHERE
CustomerName LIKE '%John%'
Thanks in advance.

You cannot use the Alias name in the same select statement because where will be processed before the select.
Make the original query as sub select and use the alias name in where clause.Try this.
SELECT *
FROM (SELECT tbl_Sales.SaleID,
tbl_Sales.CustomerID,
(SELECT Firstname + ' ' + Lastname
FROM tbl_Customers
WHERE CustomerID = tbl_Sales.CustomerID) AS CustomerName,
tbl_Sales.Price
FROM tbl_Sales) A
WHERE CustomerName LIKE '%John%'
or use Cross apply
SELECT tbl_Sales.SaleID,
tbl_Sales.CustomerID,
t.CustomerName,
tbl_Sales.Price
FROM tbl_Sales
CROSS apply (SELECT Firstname + ' ' + Lastname AS CustomerName
FROM tbl_Customers
WHERE CustomerID = tbl_Sales.CustomerID) t
WHERE t.CustomerName LIKE '%John%'

You are not allowed to pass ALIAS name in WHERE clause instead of that you should use JOIN
Try this:
SELECT S.SaleID, S.CustomerID, (C.Firstname + ' ' + C.Lastname) AS CustomerName, S.Price
FROM tbl_Sales S
INNER JOIN tbl_Customers C ON S.CustomerID = C.CustomerID
WHERE (C.Firstname + ' ' + C.Lastname) LIKE '%John%'

Instead of checking the combined value, you could check each column like this. Combining the columns and comparing is not SARGable, and will result in bad performance:
SELECT
tbl_Sales.SaleID,
tbl_Sales.CustomerID,
cus.Firstname + ' ' + cus.Lastname CustomerName,
tbl_Sales.Price
FROM
tbl_Sales
JOIN
tbl_Customers cus
ON
cus.CustomerID = tbl_Sales.CustomerID
WHERE
(cus.Firstname LIKE '%John%' or
cus.Lastname LIKE '%John%')

Related

Full outer join not including results from the second table?

I have 2 employee tables and trying to look up a user from both of them. For example:
Employees1
username full_name
fbar Foo Bar
Employees2
email full_name
sname#test.com Some Name
I'm trying to do something like this:
DECLARE #testuser VARCHAR(100)
SET #testuser = 'sname'
SELECT isnull(a.full_name, b.full_name) as full_name
FROM Employees1 as a
FULL OUTER JOIN Employees2 as b ON b.email LIKE #testuser + '%'
WHERE a.username = #testuser
If I run this then it comes out blank. But if I run the following then it shows the correct name:
SELECT full_name FROM Employees2 WHERE email LIKE #testuser + '%'
Is there a reason the full outer join isn't showing a result but the second select statement is?
If you have limiting conditions on individual tables that are separate from the outer join condition, you will need to put them in a subselect for them to work as expected.
I believe what you want is something like:
DECLARE #testuser VARCHAR(100) = 'sname'
SELECT isnull(a.full_name, b.full_name) as full_name
FROM (
SELECT *
FROM Employees1
WHERE username = #testuser
) as a
FULL OUTER JOIN (
SELECT *
FROM Employees2
WHERE email LIKE #testuser + '%'
) as b
ON b.full_name = a.full_name
Or perhaps you may just need a UNION:
SELECT full_name
FROM Employees1
WHERE username = #testuser
UNION
SELECT full_name
FROM Employees2
WHERE email LIKE #testuser + '%'
I added the full_name join condition, as I believe that is what you intended.
See this db<>fiddle.

T-SQL inner query like join based off IN results

I have a T-SQL query that has a subquery listing 2 names:
Coop
Bro
Code:
Select LastName
From Managers
Where Type = prefix;
I need to have the outer query use this above sub-query in something like an 'IN' statement, but it's not an exact match, but rather a BEGINS WITH. Something like the following with + '%':
Select *
From Employees
Where LastName In (Select LastName + '%'
From Managers
Where Type = prefix)
Desired query would return back outer query results such as:
Cooper
Coopersmith
Coopmoth
Brown
Brownly
Bronnan
...but, this is not working. I get 0 results.
You can use exists. Presumably, you intend something like this:
Select e.*
from Employees e
where exists (select 1
from managers m
where type = prefix and
e.LastName like m.LastName + '%'
)
Got it with similar to:
select * from employees e
inner join Managers m on e.lastname like m.lastname + '%' and m.type = prefix

How do I write a subquery to concatenate Last name and First name using another table in database in SQL Server?

I'm using 2 tables, Orders and Employees. Both have IDs of employees. I need to get a total amount of orders completed by each separate employee.
I want my result to be this: full name, total orders.
What I could get is: employee ID, total orders.
I can't connect Order.EmployeeID with Employees.EmployeeID, even when using CAST or CONVERT.
I can make separate queries to concat names, and to show orders by employee ID, but I can't wrap my mind how to make a subquery to give me full name of each employee and total amount of their orders.
SELECT
[dbo].[Orders].EmployeeID AS Seller,
COUNT(OrderID) AS Amount
FROM
[dbo].[Orders]
JOIN
[dbo].[Employees] ON [dbo].[Employees].EmployeeID = [dbo].[Orders].EmployeeID
GROUP BY
[dbo].[Orders].EmployeeID;
I expect the following result:
|Name |TotalOrders|
+------------+-----------+
|Johnny Bravo| 120 |
Current result however is:
|ID|TotalOrders|
+--+-----------+
|1 |120 |
Simply concatenate them, like this for example
SELECT
o.EmployeeID AS Seller,
CONCAT(e.FirstName + ' ', e.LastName) AS FullName,
COUNT(o.OrderID) AS Amount
FROM
[dbo].[Orders] o
JOIN
[dbo].[Employees] e ON o.EmployeeID = e.EmployeeID
GROUP BY
o.EmployeeID, e.FirstName, e.LastName
You could also do this
(e.FirstName + ' ' + e.LastName) as FullName
But beware of this, when one of the columns is NULL then the result will also be NULL
Then you would have to do this
(isnull(e.FirstName, '') + ' ' + isnull(e.LastName, '')) as FullName
Therefore, the CONCAT function is easier, it will convert NULL values into empty strings for you.
See also this Documentation
EDIT
As noted by Sean Lange, it is better to do
Concat(e.FirstName + ' ', e.LastName) as FullName,
in stead of
Concat(e.FirstName, ' ', e.LastName) as FullName,
Because this way you will have no leading spaces when the firstname is null
SELECT [dbo].[Orders].EmployeeID AS Seller,Concat ([Orders].FirstName,[Orders].Lastname) fullname,
COUNT(OrderID) AS Amount
FROM [dbo].[Orders]
JOIN [dbo].[Employees] ON [dbo].[Employees].EmployeeID = [dbo].[Orders].EmployeeID
GROUP BY [dbo].[Orders].EmployeeID,[Orders].FirstName,[Orders].Lastname;

Duplicate GROUP_CONCAT when using JOIN

I'm creating a sort of geocache team building system and I'm having trouble with my query.
To collate and display the individuals against the teams I'm using GROUP_CONCAT, however when I try to include the locations (listed as markers) the individuals names are being duplicated based on the number of markers.
I have put together a SQL Fiddle to explain my workings.
Here is my query:
SELECT SQL_CALC_FOUND_ROWS
map_team.id AS team_id,
map_team.name,
GROUP_CONCAT(firstname, ' ', surname SEPARATOR ', ') AS full_name
FROM map_team
LEFT JOIN members
ON members.map_team=map_team.id
WHERE members.map_team IS NOT NULL
GROUP BY map_team.name
ORDER BY map_team.name ASC
Any advice would be appreciated.
GROUP_CONCAT( distinct ... ) will not give correct answers as the team member names in a team can be same. If you want to get it in a single query you can use:
SELECT SQL_CALC_FOUND_ROWS
map_team.id AS team_id,
map_team.name,
GROUP_CONCAT(firstname, ' ', surname SEPARATOR ', ') AS full_name,
(select count(*) from map_markers where team_id = map_team.id) AS total_markers,
(select count(*) from map_markers where team_id = map_team.id and status = 'completed') AS total_completed
FROM map_team
LEFT JOIN members
ON members.map_team=map_team.id
WHERE members.map_team IS NOT NULL
GROUP BY map_team.name
ORDER BY map_team.name ASC
If you don't like the idea of a subquery in select. You need to do it separately.
Use
GROUP_CONCAT(distinct firstname ...
use following query:
SELECT SQL_CALC_FOUND_ROWS
map_team.id AS team_id,
map_team.name,
GROUP_CONCAT(distinct firstname, ' ', surname SEPARATOR ', ') AS full_name,
count(*) AS total_markers,
SUM(IF(status = 'completed', 1, 0)) AS total_completed
FROM map_team
LEFT JOIN members
ON members.map_team=map_team.id
LEFT JOIN map_markers
ON map_markers.team_id=map_team.id
WHERE members.map_team IS NOT NULL
GROUP BY map_team.name
ORDER BY map_team.name ASC

LIKE operator instead of IN operator when checking tables

I am working on an SQL script to add the ID of a customer if the phone number is found inside a table.
Below is a snippet of my code:
CREATE TABLE #Customers ( AccountNumber nvarchar(20))
CREATE TABLE #Phones ( Number nvarchar(30))
INSERT INTO #Customers (AccountNumber)
SELECT AccountNumber
FROM CustomerTable
WHERE
(CustomerTable.PhoneNumber IN (SELECT DISTINCT Number FROM #Phones))
OR
(CustomerTable.PhoneNumber2 IN (SELECT DISTINCT Number FROM #Phones))
GO
However, using those statement I am only able to check if the exact record is met within the table. For example:
If Phones.Number has a record '123456' and CustomerTables.PhoneNumber has a record '123456 7', this record record will not be obtained, even if it contains the number.
Are their any modifications I can do to my current snippet in order to apply similar logic to the LIKE operator?
This can't be done directly with the in operator, but using a query inside the exists operator should do the trick:
INSERT INTO #Customers (AccountNumber)
SELECT AccountNumber
FROM CustomerTable ct
WHERE EXISTS (SELECT *
FROM #Phones p
WHERE ct.PhoneNumber LIKE '%' + p.Number + '%' OR
ct.PhoneNumber2 LIKE '%' + p.Number + '%')
SELECT AccountNumber
FROM CustomerTable c
join #Phones p
on c.PhoneNumber like p.Number + '%' OR c.PhoneNumber2 like p.Number + '%'
I think this will also work, but i have not tested.
WITH Customers AS
(
SELECT AccountNumber , Len(PhoneNumber) as PhoneSize
FROM
)
INSERT INTO #Customers (AccountNumber)
SELECT AccountNumber
FROM CustomerTable a
Join Customers b on a.AccountNumber = b.AccountNumber
WHERE
(CustomerTable.PhoneNumber IN (SELECT DISTINCT LEft(Number,b.PhoneSize) FROM #Phones))
OR
(CustomerTable.PhoneNumber2 IN (SELECT DISTINCT LEft(Number,b.PhoneSize) FROM #Phones))