In this post, we are going to be answering 9 Complex SQL Queries which were asked by you.
1) How to trim multiple spaces into a single space?
The trick here is to use the Triple Replace Technique.
declare @str varchar(100);
Set @str = 'This is best SQL Learning Video';
-- Step 1 - Replace a single space with a combination of a space and a pipe. You can choose any other delimiter instead of a pipe and other than a space.
Select Replace(@str,' ', ' |');
-- Step 2 - Replace the reverse combination ( a pipe and a space) by an empty string.
Select Replace(Replace(@str,' ', ' |'),'| ','')
-- Step 3 - Replace the original combination (space and a pipe) by the desired delimiter (single space in this case).
Select Replace(Replace(Replace(@str,' ', ' |'),'| ',''),' |','-')
3 - How to dynamically select columns in a SELECT query?
Hint - Define a variable containing the desire columns. Construct a dynamic SQL query using the variable to fetch the column names.
declare @col varchar(100) = 'A, B, C'
declare @sql varchar(250) = 'Select ' + @col + ' from Employees'
--print(@sql)
exec(@sql)
4 - How to select customers who have ordered every single day in the last month?
We are going to use the below sample data for this example.
Create Table Orders
(OrderDate date ,
CustomerID int)
INSERT into Orders VALUES
('2023-05-01', 1), ('2023-05-02', 1), ('2023-05-03', 1), ('2023-05-04', 1), ('2023-05-05', 1),
('2023-05-01', 2), ('2023-05-03', 2), ('2023-05-01', 3), ('2023-05-02', 3), ('2023-05-03', 3)
Hint - 1 - Find the total number of days in the last month. In the below query, we subtract 1 month from the current date and then use the EOMONTH function to get the last day of the previous month. The last day decides the number of days in the month.
Select EOMONTH(DATEADD(m,-1,Getdate()))
Hint - 2 - Calculate the number of distinct Order Dates for each customer in the previous month.
Hint - 3 - If the above two counts match, then it means that the Customer placed at least one order each day of the previous month.
Select CustomerID
From Orders
Group by CustomerID
Having Count(distinct Orderdate) = DAY(EOMONTH(DATEADD(m,-1,Getdate())))
5 - How to find Top 5 and Bottom 5 Employees based on Salary in a single SQL Query?
Hint - Use ROW_NUMBER function. Sort ascending to calculate Bottom 5 and Sort descending to calculate Top 5.
With EmpSAL AS
(Select * ,
ROW_NUMBER() OVER (Order By Salary ) AS Bottom5 ,
ROW_NUMBER() OVER (Order By Salary Desc) AS Top5
FROM Employees )
Select *,
CASE WHEN Bottom5 <= 5 THEN 'Bottom'
WHEN Top5 <= 5 Then 'Top'
END as TopORBottom
FROM EmpSAL
WHERE Bottom5 <= 5 OR Top5 <= 5
6 - How to check if a column is masked or not?
Hint - Check the system table - sys.masked_columns.
--Select * from Membership;
--Select * from sys.masked_columns;
SELECT c.name as ColumnName, tbl.name as table_name, c.is_masked, c.masking_function
FROM sys.masked_columns AS c
JOIN sys.tables AS tbl
ON c.[object_id] = tbl.[object_id]
WHERE tbl.name = 'Membership' and is_masked = 1;
7 - How to remove NULL values from a LEFT JOIN?
Hint - If you need to filter out rows containing NULL values, then use IS NOT NULL in WHERE clause.
Select Dept.DeptID
FROM Dept LEFT Join Employees Emp
ON Dept.DeptID = Emp.DeptID
WHERE EmployeeID IS NOT NULL
If you need to select the NULL record, but replace its value, use a function like COALESCE to replace the NULL value from the LEFT Join.
Select Dept.DeptID, COALESCE(Emp.EmployeeID ,0)
FROM Dept LEFT Join Employees Emp
ON Dept.DeptID = Emp.DeptID
8 - How to find monthly sales from first Tuesday of current month to first Thursday of next month?
Hint - 1 - Find first day of current month and first day of next month
declare @fircurrmonth date = DATEADD(dd,1,EOMONTH(getdate(), -1));
declare @firnextmonth date = DATEADD(dd,1,EOMONTH(getdate()));
Hint - 2 - Find first Tuesday / Thursday - First subtract the weekday number of the first of the month from 7.
7 - DATEPART(dw,@fircurrmonth)
- Then add the desired weekday number. For ex - Tuesday is weekday number 3. So add 3 to the result. For Thursday, add 5.
DATEADD(dd, ((7 - DATEPART(dw,@fircurrmonth) + 3)), @fircurrmonth);
DATEADD(dd, ((7 - DATEPART(dw, @firnextmonth) + 5)), @firnextmonth)
- To make sure, we never add more than 6 days(so that we always move forward only within the 7 days), do a %7.
set @startdate = DATEADD(dd, ((7 - DATEPART(dw,@fircurrmonth) + 3)%7), @fircurrmonth);
set @enddate = DATEADD(dd, ((7 - DATEPART(dw, @firnextmonth) + 5)%7), @firnextmonth)
-- Filter on this range of dates derived above. Here is the final SQL Query.
declare @startdate date;
declare @enddate date;
declare @fircurrmonth date = DATEADD(dd,1,EOMONTH(getdate(), -1));
declare @firnextmonth date = DATEADD(dd,1,EOMONTH(getdate()));
set @startdate = DATEADD(dd, ((7 - DATEPART(dw,@fircurrmonth) + 3)%7), @fircurrmonth);
set @enddate = DATEADD(dd, ((7 - DATEPART(dw, @firnextmonth) + 5)%7), @firnextmonth)
print(@startdate);
print(@enddate)
Select *
FROM (VALUES ('2023-06-01'),('2023-07-08'),('2023-06-10'),('2023-06-21'),('2023-07-06')) as t1(col)
WHERE col >= @startdate and col <= @enddate
Hello. I have implemented the SQL from " How to dynamically convert rows into columns | Dynamic Pivot" How do i get this procedure stored as a table-valued function? I am not clear on the syntax.
ReplyDelete