Improve company productivity with a Business Account.Sign Up

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 106
  • Last Modified:

Help with SQL

I have the SQL below.  In addition to the count of records that match in deprec, deprec has an ID column.  I want a list of all IDs for the records that match, returned in one text column, like '123', '456', '666'). How can I do this?  Using a View? A stored proc?        


SELECT temp.id, name, description, (SELECT COUNT(*) FROM deprec where cal_template_id = temp.id) as count  
FROM calibration_template temp
0
HLRosenberger
Asked:
HLRosenberger
  • 4
  • 3
  • 2
1 Solution
 
Scott PletcherSenior DBACommented:
SELECT temp.id, temp.name, temp.description,
    oa1.count,
    oa2.ids
FROM calibration_template temp
OUTER APPLY (
    SELECT COUNT(*)
    FROM deprec
    WHERE deprec.cal_template_id = temp.id
) AS oa1(count)
OUTER APPLY (
    SELECT STUFF(ids, 1, 1, '')
    FROM (
         SELECT ',' + CAST(deprec.id AS varchar(10))
         FROM deprec
         WHERE deprec.cal_template_id = temp.id
         ORDER BY deprec.id FOR XML PATH('')
    ) AS derived(ids)
) AS oa2(ids)
0
 
Pawan KumarDatabase ExpertCommented:
Here it is...try

SELECT temp.id, temp.name, temp.description,r.cnt,r.cusr
FROM calibration_template ct
CROSS APPLY 
(
    SELECT COUNT(*) cnt , STUFF 
							((
								SELECT CONCAT(', ' ,a.id)
								FROM deprec a
								WHERE ( a.cal_template_id = d.id )
								FOR XML PATH('')
							) ,1,2,'') 
							AS cusr
    FROM deprec d
    WHERE d.cal_template_id = ct.id
)r


				

Open in new window

0
 
HLRosenbergerAuthor Commented:
Pawan - I get 'CONCAT' is not a recognized built-in function name.
0
What Kind of Coding Program is Right for You?

There are many ways to learn to code these days. From coding bootcamps like Flatiron School to online courses to totally free beginner resources. The best way to learn to code depends on many factors, but the most important one is you. See what course is best for you.

 
HLRosenbergerAuthor Commented:
Scott  - your method works.  Can you please explain what exactly it does?
0
 
Pawan KumarDatabase ExpertCommented:
Try this..

SELECT temp.id, temp.name, temp.description,r.cnt,r.cusr
FROM calibration_template ct
CROSS APPLY 
(
    SELECT COUNT(*) cnt , STUFF 
							((
								SELECT ', '+CAST(a.id AS VARCHAR(10))
								FROM deprec a
								WHERE ( a.cal_template_id = d.id )
								FOR XML PATH('')
							) ,1,2,'') 
							AS cusr
    FROM deprec d
    WHERE d.cal_template_id = ct.id
)r

--

Open in new window

--
0
 
Scott PletcherSenior DBACommented:
Yes.

An OUTER APPLY is effectively a type of LEFT JOIN (but with additional ways to control the results that are returned).  For every row in the left/source table -- in this case "calibration_template", alias "temp" -- each OUTER APPLY is run separately.  

Say the first id in temp is 17.  Then the first OUTER APPLY does a standard COUNT() of the number of rows where deprec.cal_template_id = 17 (the current value of temp.id).

The second outer apply gets all the deprec.id values that match 17 (the current value of temp.id), while using the XML concatenation technique to combine them into a single string.

After all the APPLYs are processed, the next row is read from the source table, and the APPLY steps are run again for that row.  And so on until all rows have been processed.


As a test, let's remove the concatenation from the second apply, and we'll get all the matching ids from deprec returned, but each in their own, separate row:

SELECT temp.id, temp.name, temp.description,
    oa1.count,
    oa2.id
FROM calibration_template temp
OUTER APPLY (
    SELECT COUNT(*)
    FROM deprec
    WHERE deprec.cal_template_id = temp.id
) AS oa1(count)
OUTER APPLY (
    SELECT deprec.id
    FROM deprec
    WHERE deprec.cal_template_id = temp.id
) AS oa2(id)
1
 
Pawan KumarDatabase ExpertCommented:
@Author - Great that it worked. the explanation is below.

Could you please choose one answer as accepted and close the question. Thanks !

As per Microsoft documentation -

The APPLY operator allows you to invoke a table-valued function for each row returned by an outer table expression of a query. The table-valued function acts as the right input and the outer table expression acts as the left input. The right input is evaluated for each row from the left input and the rows produced are combined for the final output. The list of columns produced by the APPLY operator is the set of columns in the left input followed by the list of columns returned by the right input

Type of APPLY: CROSS APPLY and OUTER APPLY.

OUTER APPLY returns both rows that produce a result set, and rows that do not, with NULL values in the columns produced by the table-valued function.
0
 
HLRosenbergerAuthor Commented:
Thanks so much!
0
 
Pawan KumarDatabase ExpertCommented:
@Author - Did you tried my solution I posted.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

A proven path to a career in data science

At Springboard, we know how to get you a job in data science. With Springboard’s Data Science Career Track, you’ll master data science  with a curriculum built by industry experts. You’ll work on real projects, and get 1-on-1 mentorship from a data scientist.

  • 4
  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now