merge two rows in return query as one - sql

I have a query that returns the people in a certain household, however the individuals show up in to separate rows, what i want to do is merge the two rows into one.
SELECT dbo.households.id, dbo.individuals.firstname, dbo.individuals.lastname
FROM dbo.households INNER JOIN
dbo.individuals ON dbo.households.id = dbo.individuals.householdID
WHERE (dbo.households.id = 10017)
Current results:
ID | First Name | Last Name |
1 | Test | Test1 |
1 | ABC | ABC1 |
Desired results:
ID | First Name | Last Name |ID1| First Name1| Last Name1|
1 | Test | Test1 |1 | ABC | ABC1 |
However if theres 3 people then it would need to merge all 3 and so on

Depending on the response to the question I asked above, below is a simple script that would compile the names into a string and then output the string (I don't have access to the syntax validator now so forgive any errors):
DECLARE
#CNT INT,
#R_MAX INT,
#H_ID INT,
#R_FIRST VARCHAR(250),
#R_LAST VARCHAR(250),
#R_NAMES VARCHAR(MAX)
SET #CNT = 0; --Counter
SET #R_NAMES = 'Names: ';
SELECT #R_MAX = COUNT(*) FROM dbo.individuals a WHERE a.householdID = #H_ID; --Get total number of individuals
PRINT(#R_MAX); --Output # of matching rows
--Loop through table to get individuals
WHILE #CNT < #R_MAX
BEGIN
--Select statement
SELECT * FROM (SELECT
#R_FIRST = b.firstname,
#R_LAST = b.lastname,
ROW_NUMBER() OVER (ORDER BY b.lastname, b.firstname) AS Row
FROM
dbo.households a INNER JOIN
dbo.individuals b ON a.id = b.householdID
WHERE
(a.id = #H_ID)) AS RN WHERE (Row = #CNT);
SET #R_NAMES = #R_NAMES + #R_FIRST + #R_LAST + '; '; --Add individual's name to name string
PRINT(CAST(#CNT AS VARCHAR) + ':' + #R_NAMES);
SET #CNT = #CNT +1; --Increase counter
END
PRINT(#R_NAMES); --Output the individuals

Provided you're using SQL Server 2005 or up, you might be able to use FOR XML PATH('') to concatenate the strings.
This should do what you want without having to do manual loops:
edit: fixed up SQL to actually work (now I have access to SQL)
SELECT households.id,
STUFF(
(
SELECT '; ' + [firstname] + '|' + lastname AS [text()]
FROM individuals
WHERE individuals.householdID = households.id
FOR XML PATH('')
)
, 1, 2, '' ) -- remove the first '; ' from the string
AS [name]
FROM dbo.households
WHERE (households.id = 10017)
This is pretty close to the format of data that you wanted.
it converts the data to XML (without any actual XML markup due to the PATH('')) and then joins it back to the header row.

Related

Using Subqueries to Define Column Alias

I have two tables which I have simplified below for clarity. One stores data values while the other defines the units and type of data. Some tests have one result, others may have more (My actual table has results 1-10):
Table 'Tests':
ID Result1 Result2 TestType(FK to TestTypes Type)
---------- ------------ ----------- -----------
1001 50 29 1
1002 90.9 NULL 2
1003 12.4 NULL 2
1004 20.2 30 1
Table 'TestTypes':
Type TestName Result1Name Result1Unit Result2Name Result2Unit ..........
------- --------- ------------ ----------- ------------ -----------
1 Temp Calib. Temperature F Variance %
2 Clarity Turbidity CU NULL NULL
I would like to use the ResultXName as the column alias when I join the two tables. In other words, if a user wants to see all Type 1 'Temp Calib' tests, the data would be formatted as follows:
Temperature Variance
------------ -----------
50 F 10.1%
20.2 F 4.4%
Or if they look at Type 2, which only uses 1 result and should ignore the NULL:
Turbidity
----------
90.9 CU
12.4 CU
I have had some success in combining the two columns of the tables:
SELECT CONCAT(Result1, ' ', ISNULL(Result1Unit, ''))
FROM Tests
INNER JOIN TestTypes ON Tests.TestType = TestTypes.Type
But I cannot figure out how to use the TestName as the new column alias. This is what I've been trying using a subquery, but it seems subqueries are not allowed in the AS clause:
SELECT CONCAT(Result1, ' ', ISNULL(Result1Unit, '')) AS (SELECT TOP(1) Result1Name FROM TestTypes WHERE Type = 1)
FROM Tests
INNER JOIN TestTypes ON Tests.TestType = TestTypes.Type
Is there a different method I can use? Or do I need to restructure my data to achieve this? I am using MSSQL.
Yes, this can be fully automated by constructing a dynamic SQL string carefully. The key points in this solution and references is listed as follows.
Count the Result variables (section 1.)
Get the new column name of ResultXName by using sp_executesql with the output definition (section 2-1)
Append the clause for the new column (section 2-2)
N.B.1. Although a dynamic table schema is usually considered a bad design, sometimes people are simply ordered to do that. Therefore I do not question the adequacy of this requirement.
N.B.2. Mind the security problem of arbitrary string execution. Additional string filters may be required depending on your use case.
Test Dataset
use [testdb];
GO
if OBJECT_ID('testdb..Tests') is not null
drop table testdb..Tests;
create table [Tests] (
[ID] int,
Result1 float,
Result2 float,
TestType int
)
insert into [Tests]([ID], Result1, Result2, TestType)
values (1001,50,29,1),
(1002,90.9,NULL,2),
(1003,12.4,NULL,2),
(1004,20.2,30,1);
if OBJECT_ID('testdb..TestTypes') is not null
drop table testdb..TestTypes;
create table [TestTypes] (
[Type] int,
TestName varchar(50),
Result1Name varchar(50),
Result1Unit varchar(50),
Result2Name varchar(50),
Result2Unit varchar(50)
)
insert into [TestTypes]([Type], TestName, Result1Name, Result1Unit, Result2Name, Result2Unit)
values (1,'Temp Calib.','Temperature','F','Variance','%'),
(2,'Clarity','Turbidity','CU',NULL,NULL);
--select * from [Tests];
--select * from [TestTypes];
Solution
/* Input Parameter */
declare #type_no int = 1;
/* 1. determine the number of Results */
declare #n int;
-- If there are hundreds of results please use the method as of (2-1)
select #n = LEN(COALESCE(LEFT(Result1Name,1),''))
+ LEN(COALESCE(LEFT(Result2Name,1),''))
FROM [TestTypes]
where [Type] = #type_no;
/* 2. build dynamic query string */
-- cast type number as string
declare #s_type varchar(10) = cast(#type_no as varchar(10));
-- sql query string
declare #sql nvarchar(max) = '';
declare #sql_colname nvarchar(max) = '';
-- loop variables
declare #i int = 1; -- loop index
declare #s varchar(10); -- stringified #i
declare #colname varchar(max); -- new column name
set #sql += '
select
L.[ID]';
-- add columns one by one
while #i <= #n begin
set #s = cast(#i as varchar(10));
-- (2-1) find the new column name
SET #sql_colname = N'select #colname = Result' + #s + 'Name
from [TestTypes]
where [Type] = ' + #s_type;
EXEC SP_EXECUTESQL
#Query = #sql_colname,
#Params = N'#colname varchar(max) OUTPUT',
#colname = #colname OUTPUT;
-- (2-2) sql clause of the new column
set #sql += ',
cast(L.Result' + #s + ' as varchar(10)) + '' '' + R.Result' + #s + 'Unit as [' + #colname + ']'
-- next Result
set #i += 1
end
set #sql += '
into [ans]
from [Tests] as L
inner join [TestTypes] as R
on L.TestType = R.Type
where R.[Type] = ' + #s_type;
/* execute */
print #sql; -- check the query string
if OBJECT_ID('testdb..ans') is not null
drop table testdb..ans;
exec sp_sqlexec #sql;
/* show */
select * from [ans];
Result (type = 1)
| ID | Temperature | Variance |
|------|-------------|----------|
| 1001 | 50 F | 29 % |
| 1004 | 20.2 F | 30 % |
/* the query string */
select
L.[ID],
cast(L.Result1 as varchar(10)) + ' ' + R.Result1Unit as [Temperature],
cast(L.Result2 as varchar(10)) + ' ' + R.Result2Unit as [Variance]
into [ans]
from [Tests] as L
inner join [TestTypes] as R
on L.TestType = R.Type
where R.[Type] = 1
Tested on SQL Server 2017 (linux docker image, latest version) on debian 10

SQL Script to find Count the number of :username Occurrences of a String

I have a table that stores information whenever user make changes to the DB. I want to extract how many times the user make changes on the date on the application. The info is normally stored for each user in one row for example :
2019-06-15randomname1:YES I DID IT 2019-06-14randomname2:HHHHHHH JJJJJJ 2019-06-14Urandomnamexxxxxx: COMMENT OF PEOPLE
What I want is to search :username to detect how many times the user has changed. In this instance. The answer suppose to be 3. How can I do it
DECLARE #logEntry VARCHAR(4000);
SET #logEntry = ':' + (SELECT PERSON_NAME FROM P_PERSON WHERE PERSON = logged_person)
SELECT
id
,value
,COUNT = (LEN(value) - LEN(REPLACE(value, #logEntry , '')))/LEN(#logEntry)
FROM table
Will I use regular expression because for this particular example the answer will be 3 since we have 3.
I have decided to use :username I am having problem with Subquery returned more than 1 value :
If I understand, you want to count the occurrence of a date in a string
DECLARE #D VARCHAR(10) = '2019-01-01';
SELECT *, LEN(V) - (LEN(REPLACE(V, #D, '')) * 10) Occurrence
FROM (VALUES('A2019-01-01B2019-01-01C2019-01-01D2019-01-01E2019-01-01F2019-01-01'))T(V);
Returns:
+--------------------------------------------------------------------+------------+
| V | Occurrence |
+--------------------------------------------------------------------+------------+
| A2019-01-01B2019-01-01C2019-01-01D2019-01-01E2019-01-01F2019-01-01 | 6 |
+--------------------------------------------------------------------+------------+
Note that this will works only when the string doesn't contains a white spaces.
If you have a white spaces, then you need to remove them first as
DECLARE #D VARCHAR(10) = '2019-01-01';
SELECT *, LEN(REPLACE(V, ' ', '')) - (LEN(REPLACE(REPLACE(V, ' ', ''), #D, '')) * 10) Occurrence
FROM (VALUES('A 2019-01-01 B 2019-01-01 C 2019-01-01 D 2019-01-01 E 2019-01-01 F 2019-01-01'))T(V);
You just changed your question, to search by a user name, but since the ':' is fixed, and if you have 2016+ version you can do as
DECLARE #D VARCHAR(10) = 'UserName1';
SELECT *,
(SELECT COUNT(1) FROM STRING_SPLIT(V, ':') WHERE Value LIKE CONCAT('%', #D, '%'))
FROM (VALUES
('2019-06-15UserName1:YES I DID IT 2019-06-14UserName2:HHHHHHH JJJJJJ 2019-06-14UserName1: COMMENT OF PEOPLE')
) T(V);
Finally, I'll recommend to re-think of that design, which is the real issue here, and read more about normalization.
UPDATE:
Here is how to count the user name with joining the two tables
SELECT *,
(
SELECT COUNT(1)
FROM STRING_SPLIT(Col, ':')
WHERE Value LIKE CONCAT('%', UserName)
) Cnt
FROM Users U JOIN Data D
ON D.Col LIKE CONCAT('%', U.UserName, '%');
Returns:
+----------+----------------------------------------------+-----+
| UserName | Col | Cnt |
+----------+----------------------------------------------+-----+
| User1 | 2019-01-01User1:YES 2019-01-02User2:No | 1 |
| User2 | 2019-01-01User1:YES 2019-01-02User2:No | 1 |
| User1 | 2019-01-01User1:YES I 2019-01-02User1:No Way | 2 |
+----------+----------------------------------------------+-----+
See how it's working on live demo
First, you have a lousy data model and processing. You should not be just adding substrings to a string. You should be adding new rows to a table. And, you should not be encoding information in a string. You should be using columns for that.
My strongest suggestion is that you fix your data model and processing.
That said, you might be stuck with this situation. THe simplest solution is just to look for
SELECT id, value,
(LEN(REPLACE(value, 'XXXXXXXXXXXXX:', 'XXXXXXXXXXXXX:1') -
LEN(value)
) as Num_Times
FROM Table;
Of course, this assumes that 'XXXXXXXXXXXXX:' doesn't actually occur in the message. If that is a possibility, see my original comment on the data structure.
The following will do as you ask, but you seriously need to reconsider how you store your data. What if instead of someone commenting "I did it", they entered "I did it on 2019-01-01"?
-- DateCount
-- Return number of occurances of ####-##-## where # is a digit
create function dbo.DateCount(#s nvarchar(max))
returns int as
begin
declare #k int = 0 -- #k holds the count so far
declare #i int = 1 -- index into string, start at first character
while #i < len(#s)-9 -- keep checking until we get to the end
begin
if substring(#s,#i,10) like '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]'
set #k = #k + 1 -- increment count if these 10 characters match
set #i = #i + 1 -- check the next character
end
return #k -- return the count
end
go
select dbo.DateCount( '2019-06-15randomname1:YES I DID IT 2019-06-14random'
+ 'name2:HHHHHHH JJJJJJ 2019-06-14Urandomnamexxxxxx: '
+ 'COMMENT OF PEOPLE' )
-- Result is 3
If you're keen on using a set-based solution instead of a while loop, you can try this:
create function dbo.DateCount(#s nvarchar(max))
returns int as
begin
declare #k int;
with A as ( select 1 as I
union all
select I+1 as I from A where I<=len(#s)-9 )
select #k=count(*) from A
where substring(#S,I,10) like '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]'
option (maxrecursion 0)
return #k
end
But, in my performance tests, I find that the set-based solution takes 50% longer.

Single column from Multiple tables SQL-SERVER 2014 Exprs

I have a DB with 50 tables having the same structure (same column names, types) clustered Indexed on the Created Date column . Each of these tables have around ~ 100,000 rows and I need to pull all of them for some columns.
select * from customerNY
created date | Name | Age | Gender
__________________________________
25-Jan-2016 | Chris| 25 | M
27-Jan-2016 | John | 24 | M
30-Jan-2016 | June | 34 | F
select * from customerFL
created date | Name | Age | Gender
__________________________________
25-Jan-2016 | Matt | 44 | M
27-Jan-2016 | Rose | 24 | F
30-Jan-2016 | Bane | 34 | M
The above is an example of the tables in the DB. I need an SQL that runs quickly pulling all the data. Currently, I am using UNION ALL for this but it takes a lot of time for completing the report. Is there another way for this where I can pull in data without using UNION ALL such as
select Name, Age, Gender from [:customerNY:customerFL:]
Out of context: Can I pull in the table name in the result?
Thanks for any help. I've been putting my mind to this but I can't find a way to do it quicker.
This dynamic SQL approach should meet your criteria, it selects table names from the schema and creates a SELECT statement at runtime for it to execute, and to meet the criteria of the UNION ALL each SELECT statement is given a UNION ALL then I use STUFF to remove the first one.
DECLARE #SQL AS VarChar(MAX)
SET #SQL = ''
SELECT #SQL = #SQL + 'UNION ALL SELECT Name, Age, Gender FROM ' + TABLE_SCHEMA + '.[' + TABLE_NAME + ']' + CHAR(13)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE 'Customer%'
SELECT #SQL = STUFF(#SQL,1,10,'')
EXEC (#SQL)
However I do not recommend using this and you should do what people have suggested in the comments to restructure your data.
Memory Optimising the test tables below gave a 7x speed increase compared to the same data in regular tables. Samples are 50 tables of 100000 rows. Please only run this on a test server as it creates filegroups/tables etc.:
USE [master]
GO
ALTER DATABASE [myDB] ADD FILEGROUP [MemOptData] CONTAINS MEMORY_OPTIMIZED_DATA
GO
ALTER DATABASE [myDB] ADD FILE ( NAME = N'Mem', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\DATA' ) TO FILEGROUP [MemOptData] --Change Path for your version
Go
use [myDB]
go
set nocount on
declare #loop1 int = 1
declare #loop2 int = 1
declare #NoTables int = 50
declare #noRows int = 100000
declare #sql nvarchar(max)
while #loop1 <= #NoTables
begin
set #sql = 'create table [MemCustomer' + cast(#loop1 as nvarchar(6)) + '] ([ID] [int] IDENTITY(1,1) NOT NULL,[Created Date] date, [Name] varchar(20), [Age] int, Gender char(1), CONSTRAINT [PK_Customer' + cast(#loop1 as nvarchar(6)) + '] PRIMARY KEY NONCLUSTERED
(
[ID] ASC
)) WITH (MEMORY_OPTIMIZED = ON, DURABILITY = SCHEMA_AND_DATA)'
exec(#sql)
while #loop2 <= #noRows
begin
set #sql = 'insert into [MemCustomer' + cast(#loop1 as nvarchar(6)) + '] ([Created Date], [Name], [Age], [Gender]) values (DATEADD(DAY, ROUND(((20) * RAND()), 0), DATEADD(day, 10, ''2018-06-01'')), (select top 1 [name] from (values(''bill''),(''steve''),(''jack''),(''roger''),(''paul''),(''ozzy''),(''tom''),(''brian''),(''norm'')) n([name]) order by newid()), FLOOR(RAND()*(85-18+1))+18, iif(FLOOR(RAND()*(2))+1 = 1, ''M'', ''F''))'
--print #sql
exec(#sql)
set #loop2 = #loop2 + 1
end
set #loop2 = 1
set #loop1 = #loop1 + 1
end
;with cte as (
Select * from MemCustomer1
UNION
Select * from MemCustomer2
UNION
...
UNION
Select * from MemCustomer50
)
select * from cte where [name] = 'tom' and age = 27 and gender = 'F'

Find a value from all table columns

I am building a functionality that will filter a data on all column table.
Let's say I have this table:
-------------------------------------
| ID | NAME | Address | Remarks |
| 1 | Manny | Phil | Boxer-US |
| 2 | Timothy | US | Boxer |
| 3 | Floyd | US | Boxer |
| 4 | Maidana | US | Boxer |
| 5 | Marquez | MEX | Boxer |
-------------------------------------
I search for "US", it should give me IDs 1-4 since "US" exists in their columns.
I could have this to filter it:
SELECT ID FROM tbl_Boxers
WHERE ID LIKE '%US%' OR NAME LIKE '%US%' OR Address LIKE '%US%' OR Remarks LIKE '%US%'
But I'm trying to avoid a long WHERE clause here since in actual, I have around 15 columns to look at.
Is there any other way to minimize the where clause?
Please help.
Thanks
The way this is normally done is to make a 'Searchable Field' column where you concatinate all search columns into one field for searching.
So while that provides an easier overview and querying it adds some management of the data you need to be aware off on inserts and updates.
Also on its own - it's not an optimal way of searching, so if performance is important - then you should look to implement full text search.
So the question is where you want to have the 'overhead' and whether that functionality your building is going to be run often or just once in a while.
If it is the former, and performance is important - look to full text. If it is just a once-in-a-while query, then I'd properly just do the long WHERE clause myself to avoid adding more overhead on the maintenance of the data
Check the following solution. Here the query is generated dynamically based on the column names in your table.
This is applicable if the given table is a physical table. This solution wont work for temporary tables or table variables.
BEGIN TRAN
--Simulate your table structure
--Should be a physical table. Cannot be a temp table or a table variable
CREATE TABLE TableA
(
ID INT,
NAME VARCHAR(50),
ADDRESS VARCHAR(50),
REMARKS VARCHAR(50)
)
--Added values for testing
INSERT INTO TableA(ID, name , address ,remarks) VALUES(1,'Manny','Phil','Boxer-US')
INSERT INTO TableA(ID, name , address ,remarks) VALUES(2,'Timothy','US','Boxer')
INSERT INTO TableA(ID, name , address ,remarks) VALUES(3,'Floyd','US','Boxer')
INSERT INTO TableA(ID, name , address ,remarks) VALUES(4,'Maidana','US','Boxer')
INSERT INTO TableA(ID, name , address ,remarks) VALUES(5,'Marquez',' MEX','Boxer')
--Solution Starts from here
DECLARE #YourSearchValue VARCHAR(50)--Will be passed
SET #YourSearchValue = 'US' --Simulated passed value
CREATE TABLE #TableCols
(
ID INT IDENTITY(1,1),
COLUMN_NAME VARCHAR(1000)
)
INSERT INTO #TableCols
(COLUMN_NAME)
SELECT COLUMN_NAME
FROM information_schema.columns
WHERE table_name = 'TableA';
DECLARE #STARTCOUNT INT, #MAXCOUNT INT, #COL_NAME VARCHAR(1000), #QUERY VARCHAR(8000), #SUBQUERY VARCHAR(8000)
SELECT #STARTCOUNT = 1, #MAXCOUNT = MAX(ID) FROM #TableCols;
SELECT #QUERY = '', #SUBQUERY = ''
WHILE(#STARTCOUNT <= #MAXCOUNT)
BEGIN
SELECT #COL_NAME = COLUMN_NAME FROM #TableCols WHERE ID = #STARTCOUNT;
SET #SUBQUERY = #SUBQUERY + ' CONVERT(VARCHAR(50), ' + #COL_NAME + ') LIKE ''%' + #YourSearchValue + '%''' + ' OR ';
SET #STARTCOUNT = #STARTCOUNT + 1
END
SET #SUBQUERY = LEFT(#SUBQUERY, LEN(#SUBQUERY) - 3);
SET #QUERY = 'SELECT * FROM TableA WHERE 1 = 1 AND (' + #SUBQUERY + ')'
--PRINT (#QUERY);
EXEC (#QUERY);
ROLLBACK
Hope this helps.

Joining Tables and Displaying Result as Text, in one column

I need to join two columns from two tables and display them in a specific order
Table1 and ColumnNM
Table2 and ColumnDESC
The Primary Key is ColumnID
I have multiple rows of ColumnDESC for each ColumnNM. So i have to display in the following format:
ColumnID ColumnNM
-------------------
ColumnDESC
ColumnDESC
ColumnDESC
ColumnDESC
ColumnID ColumnNM
-------------------
ColumnDESC
ColumnDESC
ColumnID ColumnNM
-------------------
ColumnDESC
ColumnDESC
ColumnDESC
I have to display results to text, instead of grid. Any suggestions on how to do this?
I have to create it as a stored procedure. Any help is appreciated. Below is as far as i got:
DECLARE #Name nvarchar(max),
#Lesson nvarchar(max),
#lb nvarchar(max)
SET #lb = '----------------------------------------------------'
SELECT #Name = Module.Name
FROM Module
JOIN Lesson ON Module.ModuleSequence = Lesson.ModuleSequence
WHERE Module.ModuleSequence = 1
PRINT '1 ' + #Name
PRINT #lb
SELECT Lesson.Description
FROM Module
JOIN Lesson ON Module.ModuleSequence = Lesson.ModuleSequence
WHERE Module.ModuleSequence = 1
But I think I'm way off.
..........................................OKAY, EDIT, after John Tabernik suggestion i got this......................................
(P.S. sorry about adding a comment to your answer, just learning how to use stackoverflow)
SELECT M.Name, L.Description
FROM Module M
JOIN Lesson L
ON M.ModuleSequence = L.ModuleSequence
ORDER BY M.Name, L.Description
I end up getting the M.Name repeated four times as there are four different L.Description for the first M.Name, and different amounts for all the other M.Name's.
Example:
M.Name | L.Description
-----------------------------
A | 1
A | 2
A | 3
B | 1
B | 2
C | 1
C | 2
C | 3
But i need it to output like this:
A |
-----
1 |
2 |
3 |
B |
-----
1 |
2 |
C |
-----
1 |
2 |
How important is the sections being set apart with the header and "-------" line like you have it? Simple SQL would not do this, but if the results can be all together and simply ordered, it is really easy.
You just want something like this:
SELECT column1, column2
FROM table1 T1
JOIN table2 T2
on T1.id = T2.foreignkey
ORDER BY column1, column2
You can make use of whatever pulls this data out to format it, but this general approach will get you the data, sorted the way you want. Good luck!
Sorry for getting back a bit late, but I have solved what I needed. I think I worded the question a bit off. Nonetheless, below is the code i needed. Hope it inspires anyone who has similiar problem:
CREATE PROCEDURE ShowModuleWithLessons
#CourseID int = 0
AS
BEGIN
SET NOCOUNT ON
DECLARE #MS INT
DECLARE #ModuleCount INT
SET #MS = 0
SET #ModuleCount = (Select COUNT(Module.ModuleSequence) FROM Module WHERE Module.CourseID = #CourseID)
IF EXISTS (SELECT * FROM Module WHERE Module.CourseID = #CourseID)
BEGIN
WHILE #MS < #ModuleCount
BEGIN
SET #MS=#MS+1
DECLARE #Name nvarchar(max),
#Lesson nvarchar(max),
#CID INT
SELECT #Name = Module.Name,
#CID = #MS
FROM Module
JOIN Lesson ON Module.ModuleSequence = Lesson.ModuleSequence
WHERE Module.ModuleSequence = #MS
PRINT CONVERT(VARCHAR(2),#MS) + '. ' + #Name
SELECT Lesson.Description AS Lessons
FROM Module
JOIN Lesson ON Module.ModuleSequence = Lesson.ModuleSequence
WHERE Module.ModuleSequence = #MS
END
END
ELSE
BEGIN
PRINT 'Course with ID ' + CONVERT(VARCHAR(2),#CourseID) + ' does not exists'
END