How we can use CTE in subquery in sql server? - sql

How we can use a CTE in a subquery in SQL Server?
like:
SELECT id (I want to use CTE here), name FROM table_name

Just define your CTE on top and access it in the subquery?
WITH YourCTE(blubb) AS
(
SELECT 'Blubb'
)
SELECT id,
(SELECT blubb FROM YourCTE),
name
FROM table_name

It doesn't work:
select id (I want to use CTE here), name from table_name
It's not possible to use CTE in sub queries.
You can realize it as a work around:
CREATE VIEW MyCTEView AS ..here comes your CTE-Statement.
Then you are able to do this:
select id (select id from MyCTEView), name from table_name

Create a view with CTE/ Multiple CTEs with UNION sets of all CTEs
CREATE VIEW [dbo].[_vEmployees]
AS
WITH
TEST_CTE(EmployeeID, FirstName, LastName, City, Country)
AS (
SELECT EmployeeID, FirstName, LastName, City, Country FROM Employees WHERE EmployeeID = 4
),
TEST_CTE2
AS (
SELECT EmployeeID, FirstName, LastName, City, Country FROM Employees WHERE EmployeeID = 7
)
SELECT EmployeeID, FirstName, LastName, City, Country FROM TEST_CTE UNION SELECT * FROM TEST_CTE2
GO
Now, use it into sub query
SELECT * FROM Employees WHERE EmployeeID IN (SELECT EmployeeID FROM _vEmployees)

Related

SQL Select column which is not used in select section of subquery which find duplicates

I am trying to find in my database records which has duplicated fields like name, surname and type.
Example:
SELECT name, surname, type, COUNT(*)
FROM customers
GROUP BY name, surname
HAVING COUNT(*)>1
Query results:
Robb|Stark|1|2
Tyrion|Lannister|1|3
So we have duplicated customer with name and surname "Robb Stark" 2 times and "Tyrion Lannister" 3 times
Now, I want to know the id of these records.
I found similar problem described here:
Finding duplicate values in a SQL table
there is answer but no example.
Use COUNT as an analytic function:
WITH cte AS (
SELECT *, COUNT(*) OVER (PARTITION BY name, surname) cnt
FROM customers
)
SELECT * -- return all columns
FROM cte
WHERE cnt > 1
ORDER BY name, surname;
The simplest way will be to use the EXISTS as follows:
SELECT t.*
FROM customers t
where exists
(select 1 from customers tt
where tt.name = t.name
and tt.surname = t.surname
and tt.id <> t.id)
Or use your original query in IN clause as follows:
select * from customers where (name, surname) in
(SELECT name, surname
FROM customers
GROUP BY name, surname
HAVING COUNT(*)>1)
If you want one row per group of duplicate, with the list of id in a comma separated string, you can just use string aggration with your existing query:
SELECT name, surname, COUNT(*) as cnt,
STRING_AGG(id, ',') WITHIN GROUP (ORDER BY id) as all_ids
FROM customers
GROUP BY name, surname
HAVING COUNT(*) > 1

SQL Union Select for alternate data

I created an sql query with union select and here is the query to join the two columns into one.
(select top 10 FirstName from Users) union (select top 10 LastName from Users)
Here is the Result:
QUERY RESULT 1
And here is the original data for the result 1 of union select.
ORIGINAL DATA
So, here is my problem.
How do I select the data of each firstname and lastname with the same column but the first one is firstname and the second one is lastname. For example:
Tumbaga Temp - <FirstName>
Villamor - <LastName>
Jun - <FirstName>
Villamor - <LastName>
FN83 - <FirstName>
Lising Geron - <LastName>
So on and so fort.
I am new in sql query. Thanks for your help.
We add a common row_number() to both parts to essentially group them, then order by this and the name type to display in clusters of first/last pairs
select 'First' as thename,
Firstname,
row_number() over(order by firstname) rn
from Users
union all
select 'Last',
Lastname,
row_number() over(order by firstname)
from users
order by rn, thename
If you only want the 1st 10, then wrap this and add a clause
select *
from
(
select 'First' as thename,
Firstname,
row_number() over(order by firstname) rn
from Users
union all
select 'Last',
Lastname,
row_number() over(order by firstname)
from users
)
where rn <=10
order by rn, thename
No need to use union, As per your description You have two columns 'firstName' and 'lastName' in a table and you want both in a single column. Just try the following query-:
select FirstName+' '+LastName as FullName from Users
SQL Server
you can add a column to both queries with your favourite data to be selected.
(select top 10 FirstName, 'FirstName' as NameType from SysUser) union (select top 10 LastName, 'LastName' as NameType from SysUser)

What is the easiest way to getting distinct count in SQL Server

I've a distinct query as like below for three columns. My requirement is that I need a count of distinct of these three columns.
select distinct empid, empname, salary from employee
This is the following query used to getting the count of the table in normal case, but I needed that distinct count, how can I make a query ?
select count(empid) from employee
select count(*) from
(
select distinct empid, empname, salary from employee
) x
if you don't want to use a sub select just use group by
Select Count(*) FROM employee GROUP BY empid, empname, salary

Coun(*),distinct and column

How to accomplish like this in sqlserver
select firstname,count(*) from
(select distinct firstname,lastname,amount
from emp)
group by firstname
This works in oracle.
I don't understand what are you trying to do, but your query could be written this way:
SELECT firstname, COUNT(*)
FROM emp
GROUP BY firstname;
Or:
select firstname, count(*)
from
(
select distinct firstname, lastname, amount
from emp
) AS t
group by firstname;
You can also use the DISTINCT keyword inside the COUNT; something like this: COUNT(DISTINCT columnanme) instead.
Or:
select firstname, lastname, amount, COUNT(*)
from emp
group by firstname, lastname, amount;
Here's an example from some stuff where I work that does basically the same thing:
SELECT SYS_CSL, COUNT(SYS_CSL)
FROM (
SELECT SYS_CSL
FROM [VANTAGE_READ].CSL_SERV_RANK
WHERE AGNT_CSL = 0
AND (STOP_DTE_CSL > GETDATE() OR STOP_DTE_CSL IS NULL)
) t1 GROUP BY sys_csl
You need to name the derived table
select firstname, count(*)
from (select distinct firstname,lastname,amount from emp) derived
group by firstname

SQL DISTINCT [Alternative Using]

I have a simple query on Oracle.
SELECT DISTINCT City, Name, Surname FROM Persons
Is there any alternative sql query for the same query without DISTINCT ?
Have a look at this article
Example as;
select City
from (
select City,
row_number() over
(partition by City
order by City) rownumber
from Persons
) t
where rownumber = 1
SELECT City, Name, Surname FROM Persons
UNION
SELECT City, Name, Surname FROM Persons
SELECT First(City), First(Name), First(Surname)
FROM Persons
GROUP BY City, Name, Surname