carriage return in sql server 2012 - sql

Hey I am using the following query to display the problem list separated by commas.
SELECT tt.VrNo, STUFF((select ','+ Er1.ErrorDesc
from ( select * from CallRegErrors )as Main
left join ErrorMaster ER1 on Main.ErrorCode=ER1.ErrorCode
WHERE (main.VrNo = tt.VrNo)
FOR XML PATH('')) ,1,1,'') AS Problemlist
query is giving the output like a,b,c,d etc
But my actual requirement is I want to display each error description in a new line like,
a
b
c
d
etc
I tried the following query for it:
SELECT tt.VrNo, STUFF((select char(13)+char(10)+ Er1.ErrorDesc
from ( select * from CallRegErrors )as Main
left join ErrorMaster ER1 on Main.ErrorCode=ER1.ErrorCode
WHERE (main.VrNo = tt.VrNo)
FOR XML PATH('')) ,1,1,'') AS Problemlist
and also i have used
SELECT tt.VrNo,Replace(STUFF((select ','+ Er1.ErrorDesc as [text()] from ( select * from CallRegErrors )as Main left join ErrorMaster ER1 on Main.ErrorCode=ER1.ErrorCode
WHERE (main.VrNo = tt.VrNo)
FOR XML PATH('')),1,1,''),',',char(13)+char(10)) AS Problemlist
from (select main.VrNo, Er1.ErrorDesc from ( select * from CallRegErrors )as Main left join ErrorMaster ER1 on Main.ErrorCode=ER1.ErrorCode )as tt
group by tt.VrNo
but now get the problem list seperated by spaces instead of commas after using the above query
but its does not give the output that i want.
please help..
Thanks in advance

I think we need more information before we can help you.
I think you are trying to format the information at the child level in a parent child relationship into a list. You probably saw something like this blog on the web.
However, your query is not correctly formatted.
Is the ErrorMaster (Production.ProductCategory) the parent and CallRegErrors (SUB.ProductCategoryID) the child?
If so just change the query to those table name field names for it to work.
I used the REPLACE function on the overall result to change COMMAS to CR + LF.
-- Sample database
USE AdventureWorks2012
GO
-- Change SQL from www.sqlandme.com for this users problem
SELECT
CAT.Name AS [Category],
REPLACE(STUFF((
SELECT ',' + SUB.Name AS [text()]
FROM Production.ProductSubcategory SUB
WHERE SUB.ProductCategoryID = CAT.ProductCategoryID
FOR XML PATH('')
), 1, 1, '' ), ',', CHAR(13) + CHAR(10))
AS [Sub Categories]
FROM Production.ProductCategory CAT
You can only see carriage returns in the output window when the type is set to TEXT in SSMS.
I hope this solves your problem. If not, please write back with more information!!

Related

The multi-part identifier could not be bound - stuff cmd

I'm attempting a Stuff Cmd to combine multiple rows to a single entry. I keep getting "The multi-part identifier "SPCLT.CD_VAL_DESC" could not be bound." (under the first SELECT statement)
STUFF(
(SELECT
**',' + SPCLT.CD_VAL_DESC**
FROM
(
SELECT DISTINCT
SPCLT.CD_VAL_DESC SPECIALTY
FROM PIN_STATUS PS
INNER JOIN PROV_TYPE_SPCLT SPC
ON PS.PROV_ID = SPC.PROV_ID
AND SPC.VLDT_IND = 'Y'
INNER JOIN CODE_REF SPCLT
ON SPC.SPCLT_CD = SPCLT.CD_VAL
AND SPCLT.CD_REF_NM = 'SPECIALTY'
AND SPCLT.VLDT_IND = 'Y'
WHERE SPC.VLDT_IND = 'Y'
) SPCLTY
for xml
path('')
)
,1,1,'') SPECIALTIES
You need to pay attention to the format of your SQL, and then the answer would probably jump out and bite you on the nose... happens to everyone.
Your query:
STUFF(
(
SELECT
',' + SPCLT.CD_VAL_DESC
FROM
(
SELECT DISTINCT
SPCLT.CD_VAL_DESC SPECIALTY
FROM PIN_STATUS PS
INNER JOIN PROV_TYPE_SPCLT SPC
ON PS.PROV_ID = SPC.PROV_ID
AND SPC.VLDT_IND = 'Y'
INNER JOIN CODE_REF SPCLT
ON SPC.SPCLT_CD = SPCLT.CD_VAL
AND SPCLT.CD_REF_NM = 'SPECIALTY'
AND SPCLT.VLDT_IND = 'Y'
WHERE SPC.VLDT_IND = 'Y'
) SPCLTY
for xml path('')
)
,1,1,'') SPECIALTIES
...is divided into sub-queries. The STUFF() function is acting on the first SELECT beneath it.
That first SELECT is taking data FROM a sub-query, which has been aliased as SPCLTY. So, naturally, within that SELECT, you need to be referencing SPCLTY and not SPCLT.
Adding a bit of whitespace makes it a little clearer, I think.

display more than one value using a SQL query

I am trying to display multiple authors per title in a single column. At the moment there a repeating rows, due to the fact that some Titles have more than 1 FirstName. Is there a form of concatenation that can be used to resolve this and display all the authors in a single filed and perhaps separated by a comma.
This is my current query:
SELECT
Submission.Title, Researcher.FirstName, Submission.Type
FROM
Submission
INNER JOIN
((Faculty
INNER JOIN
School ON Faculty.FacultyID = School.[FacultyID])
INNER JOIN
(Researcher
INNER JOIN
ResearcherSubmission ON Researcher.ResearcherID = ResearcherSubmission.ResearcherID)
ON School.SchoolID = Researcher.SchoolID)
ON Submission.SubmissionID = ResearcherSubmission.SubmissionID
GROUP BY
Submission.Title, Researcher.FirstName, Submission.Type;
This the output it generates:
[
this is the output I am trying to generate:
Title FirstName Type
---------------------------------------------------------------------------
21st Century Business Matthew, Teshar Book Chapter
A Family Tree... Keshant, Lawrence Book Chapter
Benefits of BPM... Jafta Journal Article
Business Innovation Matthew, Morna, Teshar Book Chapter
You may inclde the concantenation logic within a CROSS APPLY
SELECT
Submission.Title
, CA.FirstNames
, Submission.Type
FROM Submission
CROSS APPLY (
SELECT
STUFF((
SELECT /* DISTINCT ??? */
', ' + r.FirstName
FROM ResearcherSubmission rs
INNER JOIN Researcher r ON r.ResearcherID = rs.ResearcherID
WHERE Submission.SubmissionID = rs.SubmissionID
FOR XML PATH (''), TYPE
).value('.', 'NVARCHAR(MAX)'), 1, 2, ' ')
) AS CA (FirstNames)
GROUP BY
Submission.Title
, CA.FirstNames
, Submission.Type
;
NB: I'm not sure if you need to include DISTINCT into the subquery when concatenating the names, e.g. if these was 'Jane' (Smith) and 'Jane' (Jones) do you want the final list as: 'Jane' or 'Jane, Jane'?
You can do this in your application logic as well.
But if you want to do this with a query. You should be able do something like this:
SELECT DISTINCT
sm.Title,
STUFF(
(SELECT ', ' + r.FirstName
FROM ResearcherSubmission rs
INNER JOIN Researcher r ON r.ResearcherID = rs.ResearcherID
WHERE sm.SubmissionID = rs.SubmissionID
FOR XML PATH('')), 1, 2, '') AS FirstNames,
sm.Type
FROM Submission sm
You can use the below query to generate the o/p as you want from the o/p that you have got.
CREATE TABLE #temptable(Title VARCHAR(200), FirstName VARCHAR(200), Type VARCHAR(200))
INSERT INTO #temptable
SELECT 'Book1','Matt','Chapter' UNION
SELECT 'Book1','Tesh','Chapter' UNION
SELECT 'BPM','Jafta','Article' UNION
SELECT 'Ethics','William','Journal' UNION
SELECT 'Ethics','Lawrence','Journal' UNION
SELECT 'Ethics','Vincent','Journal' UNION
SELECT 'Cellular','Jane','Conference'
SELECT Title
,STUFF((SELECT ', ' + CAST(FirstName AS VARCHAR(10)) [text()]
FROM #temptable
WHERE Title = t.Title
FOR XML PATH(''), TYPE)
.value('.','NVARCHAR(MAX)'),1,2,' ') List_Output
,Type
FROM #temptable t
GROUP BY Title,Type

Convert a query of views into a single query with derived tables

Is it possible to convert (as in get the query as text) a query that consists of a lot of views within views into a query that is just based on the original tables?
The obvious is to go through all the views and then do it manually but wondered whether or not there was a quicker way?
It's not pretty, and like #David Faber commented, not sure how practical this will be, but here goes...
There's a whole lot of assumptions that one has to make for this to work, like
All of the views start with SELECT. (no CTE's)
The view is not enclosed in [ ] when referenced in another view
View names don't have spaces in them
This version only goes 1 level deep, but it should be possible to resolve any additional views you find in the output in a similar fashion.
And probably some more I didn't think of
I'm using the sys tables, and not the newer schema information objects, simply because I know the sys table structure better.
Assuming the following view
CREATE VIEW VW_DUMMY
AS
SELECT c.Name as Company, g.Name as [Group], gu.UserId
FROM VW_Company c
JOIN VW_Group g ON c.Id = g.CompanyId
JOIN VW_GroupUser gu ON g.Id = gu.GroupId AND gu.CompanyId = c.Id
Here's what I did.
1) Grab the view definition from syscomments for VW_DUMMY.
2) Strip off the CREATE VIEW part
2) Grab a list of objects that VW_DUMMY depends on from sysdepends
3) Grab the view definition from syscomments for all the dependant objects.
4) Strip off the CREATE VIEW part
5) Replace the name of the 'depends' object in the original view with the
definition...
1)
DECLARE #SQL VARCHAR(MAX);
SET #SQL = REPLACE((
SELECT c.text AS [text()]
FROM syscomments c
WHERE c.id = OBJECT_ID('VW_DUMMY')
FOR XML PATH('')), '
', '');
2)
SET #SQL = SUBSTRING(#SQL, PATINDEX('%SELECT%', #SQL), LEN(#SQL))
3), 4) and 5)
SELECT #SQL = REPLACE(#SQL, ' ' + name + ' ', '(' + SUBSTRING(text, PATINDEX('%SELECT%', text), LEN(text)) + ') ')
FROM (
SELECT DISTINCT OBJECT_NAME(depid) as name,
REPLACE((
SELECT c.text AS [text()]
FROM syscomments c
WHERE c.id = d.depid
FOR XML PATH('')), '
', '') as text
FROM sysdepends d
WHERE d.id = OBJECT_ID('VW_DUMMY')
AND exists(select 1 from sysobjects c where c.id = d.depid and c.type='V')) data
SELECT #SQL
I tried in on VW_DUMMY in my database, and the output is some of the worst formatted code that you might ever see, but the result is the same as the view.
Here's the output (bad formatting is deliberate)
SELECT c.Name as Company, g.Name as [Group], gu.UserId
FROM(SELECT *
FROM Company
) c
JOIN(SELECT *
FROM [Group]
) g ON c.Id = g.CompanyId
JOIN(SELECT *
FROM [GroupUser]
) gu ON g.Id = gu.GroupId AND gu.CompanyId = c.Id
Does that help?

How to concatenate distinct columns of otherwise duplicate rows into one row without using FOR XML PATH('')?

I have this query:
SELECT DISTINCT
f1.CourseEventKey,
STUFF
(
(
SELECT '; ' + Title
FROM (
SELECT DISTINCT
ces.CourseEventKey,
f.Title
FROM CourseEventSchedule ces
INNER JOIN Facility f ON f.FacilityKey = ces.FacilityKey
WHERE ces.CourseEventKey IN
(
SELECT CourseEventKey
FROM #CourseEvents
)
) f2
WHERE f2.CourseEventKey = f1.CourseEventKey
FOR XML PATH('')
), 1, 2, ''
)
FROM (
SELECT DISTINCT
ces.CourseEventKey,
f.Title
FROM CourseEventSchedule ces
INNER JOIN Facility f ON f.FacilityKey = ces.FacilityKey
WHERE ces.CourseEventKey IN
(
SELECT CourseEventKey
FROM #CourseEvents
)
) f1
It produces this result set:
CourseEventKey Titles
-------------- ----------------------------------
29 Test Facility 1
30 Memphis Training Room
32 Drury Inn & Suites Creve Coeur
The data is accurate, but I can't have FOR XML PATH('') because it escapes certain special characters.
To be clear, I'm using FOR XML PATH('') because it is possible for records with the same CourseEventKey to have multiple Facility titles associated with them.
How can I retain the data returned by this query without using FOR XML PATH('')?
Change the "for xml path('') )" section to "for xml path(''), root('root'), type).query('root').value ('.', 'varchar(max)')" this will unescape the characters correctly.
Sorry for the poor formatting but not at my computer right now. I can give a full example later if you need.

Visual Studio 2010 and Query Designer SQL Problem with XML Path

I have an awesome Visual Studio 2010 SQL frustration:
I found code on StackOverflow on how to concatenate strings from multiple rows onto a single row by using FOR XML PATH('').
When I write the following line in Query and View Designer (because, presumably, there is no other way to write SQL in Visual Studio and then save it as a "View"), I get results that are not what I want:
Code:
Names AS
(SELECT DISTINCT
Z.code,
(SELECT DISTINCT CAST(B.fname + ' ' + B.lname + ' ' AS VARCHAR(MAX))
FROM Records AS A LEFT OUTER JOIN Employees AS B ON A.id = B.id
WHERE (A.code = Z.code) FOR XML PATH('')) AS EmployeeNames
FROM Employees AS Z)
I get a result like:
Code EmployeeNames
---- -------------------------
1234 <Expr1>First Last</Expr1>
Why? Because Visual Studio 2010, in all it's glory, adds "as Expr1" to the following:
(SELECT DISTINCT CAST(B.fname + ' ' + B.lname + ' ' AS VARCHAR(MAX))
FROM Records AS A LEFT OUTER JOIN Employees AS B ON A.id = B.id
WHERE (A.code = Z.code) FOR XML PATH('')) *as Expr1*
Is there any work-around for this? I've noticed that the problem comes with the Query and View Designer Parser... and I can intentionally break the parser by putting a random function that the parser doesn't support (like OVER()) somewhere in my code. This fixes the problem, and removes the XML tags, but seems unnecessary.
Does anyone else have this problem? Does anyone know a work-around?
Thank you very much for your time and effort with my problem.
I ran into something simular and the fix for me was to define the Cast in each case.
Example:
Names AS
(SELECT DISTINCT
Z.code,
(SELECT DISTINCT CAST(B.fname AS varchar(10) + ' ' + CAST(B.lname AS varchar(10) + ' ')
FROM Records AS A LEFT OUTER JOIN Employees AS B ON A.id = B.id
WHERE (A.code = Z.code) FOR XML PATH('')) AS EmployeeNames
FROM Employees AS Z)