Showing posts with label concatenate. Show all posts
Showing posts with label concatenate. Show all posts

Friday, March 23, 2012

Grouping & Concatenation?

Hello,

I have a report with a table containing 2 groups (Role and Person, where person is a subgroup of role). I am trying to concatenate the names of a series of persons who are grouped by their role within an organisation so that a report that would usually appear as:
...
Board of Directors
Director1
DIrector2
Director3
Advisory Board
Adv1
Adv2...
...
Will appear as:
...
Board of Directors
Director1, Director2, Director3
Advisory Board
Adv1, Adv2...
...
This can easily be done in crystal reports by concatenating the person names in the header section of group 2 (persons) and printing the result in the footer section of group 1 (role). However, in SSRS it appears that a group's footer is output before the contents (details or subgroup) of the group and this throws out the whole concatenation process so that I end up with:
...
Board of Directors
Advisory Board
Director1, Director2, Director3
...
How can I get around this?
Thank you,
Stephen.

You may want to read this blog article: http://blogs.msdn.com/bwelcker/archive/2005/05/10/416306.aspx

It describes the custom aggregate approach. In your particular example, the custom code function would just concatenate strings (instead of adding certain values as shown in the blog article).

-- Robert

|||

Thanks for the response. I will give that a try and let you know how I get on.

Thanks again,

Stephen.

|||

I've taken a look at the suggested solution and, correct me if I'm wrong but it appears to be doing much the same as what I am already doing. In the header of the inner group, I am concatenating the list of persons:
...
Shared _memberList As String

Shared Function AddMember(ByVal member As String) As String
If (_memberList Is Nothing) Then _memberList = String.Empty
If (_memberList.IndexOf(member) = -1) Then _memberList &= member
Return String.Empty
End Function
...
Then in the footer of the outer group, I am printing the concatenated list:
...
Shared Function GetMembers() As String
Dim tempList As String = _memberList
_memberList = String.Empty
Return tempList
End Function
...
As I say, this is causing problems because it appears that the outer group's footer is processed before the inner group's header (which just doesn't seem logical to me), so the list of persons are allways printed either in the following group or following record.

|||

OK. I've finally found a solution. Instead of using a table to achieve this, I place a list object inside a table header and manually configured the groups within the list object. This way, I was able to ensure the order of precedence was header->inner group->footer.

Regards,

Stephen.

|||

Can you please be more specific? Did you create a separate dataset for the list and added groupings in that? Did you hide the list display in the header and took the concatenated result from it and displayed in the body of the table?

Thank you,

Vinita

Grouping & Concatenation?

Hello,

I have a report with a table containing 2 groups (Role and Person, where person is a subgroup of role). I am trying to concatenate the names of a series of persons who are grouped by their role within an organisation so that a report that would usually appear as:
...
Board of Directors
Director1
DIrector2
Director3
Advisory Board
Adv1
Adv2...
...
Will appear as:
...
Board of Directors
Director1, Director2, Director3
Advisory Board
Adv1, Adv2...
...
This can easily be done in crystal reports by concatenating the person names in the header section of group 2 (persons) and printing the result in the footer section of group 1 (role). However, in SSRS it appears that a group's footer is output before the contents (details or subgroup) of the group and this throws out the whole concatenation process so that I end up with:
...
Board of Directors
Advisory Board
Director1, Director2, Director3
...
How can I get around this?
Thank you,
Stephen.

You may want to read this blog article: http://blogs.msdn.com/bwelcker/archive/2005/05/10/416306.aspx

It describes the custom aggregate approach. In your particular example, the custom code function would just concatenate strings (instead of adding certain values as shown in the blog article).

-- Robert

|||

Thanks for the response. I will give that a try and let you know how I get on.

Thanks again,

Stephen.

|||

I've taken a look at the suggested solution and, correct me if I'm wrong but it appears to be doing much the same as what I am already doing. In the header of the inner group, I am concatenating the list of persons:
...
Shared _memberList As String

Shared Function AddMember(ByVal member As String) As String
If (_memberList Is Nothing) Then _memberList = String.Empty
If (_memberList.IndexOf(member) = -1) Then _memberList &= member
Return String.Empty
End Function
...
Then in the footer of the outer group, I am printing the concatenated list:
...
Shared Function GetMembers() As String
Dim tempList As String = _memberList
_memberList = String.Empty
Return tempList
End Function
...
As I say, this is causing problems because it appears that the outer group's footer is processed before the inner group's header (which just doesn't seem logical to me), so the list of persons are allways printed either in the following group or following record.

|||

OK. I've finally found a solution. Instead of using a table to achieve this, I place a list object inside a table header and manually configured the groups within the list object. This way, I was able to ensure the order of precedence was header->inner group->footer.

Regards,

Stephen.

|||

Can you please be more specific? Did you create a separate dataset for the list and added groupings in that? Did you hide the list display in the header and took the concatenated result from it and displayed in the body of the table?

Thank you,

Vinita

Wednesday, March 21, 2012

GROUPBY ??

I have a table with two columns item_code and Alternate_reference. During a
select I would like to concatenate Alternate_reference if there are more tha
n
one for an Item_code. Is this possible and if so how do you accomplish this.
Here is and sample of the data
Item Code Alternate_reference
123456 85694
123456 86623
123456 25364
The resulting value
Item Code Alternate_reference
123456 85694, 86623, 25364See if this helps:
http://groups-beta.google.com/group...
5bf366dd9e73e
AMB
"Sherry" wrote:

> I have a table with two columns item_code and Alternate_reference. During
a
> select I would like to concatenate Alternate_reference if there are more t
han
> one for an Item_code. Is this possible and if so how do you accomplish thi
s.
> Here is and sample of the data
>
> Item Code Alternate_reference
> 123456 85694
> 123456 86623
> 123456 25364
>
> The resulting value
> Item Code Alternate_reference
> 123456 85694, 86623, 25364|||Sherry, I've needed to do something like this for user display purposes
and I've done it in application/script code. Very simple loop and
concat operation. Probably not as simple in SQL, so if you can do it
client-side you'll be better off.|||Thanks Alehandro...I'll look it over.
"Alejandro Mesa" wrote:
> See if this helps:
> http://groups-beta.google.com/group...d85bf366dd9e73e
>
> AMB
> "Sherry" wrote:
>|||Alejandro and Sherry have giving you the correct answer but let me repeat
it.
Do this client side.
Reasons:
Databases are not built to do this efficiently (it's not their job).
It's simple to do this client side.
Your application will possible (probably) be faster if you do this client
side.
I tested the last point out myself and the speed-gain was remarkable.
YMMV
"Sherry" <Sherry@.discussions.microsoft.com> wrote in message
news:65EF5552-90E1-4122-990D-B27E4BD8225D@.microsoft.com...
>I have a table with two columns item_code and Alternate_reference. During
>a
> select I would like to concatenate Alternate_reference if there are more
> than
> one for an Item_code. Is this possible and if so how do you accomplish
> this.
> Here is and sample of the data
>
> Item Code Alternate_reference
> 123456 85694
> 123456 86623
> 123456 25364
>
> The resulting value
> Item Code Alternate_reference
> 123456 85694, 86623, 25364

Monday, March 12, 2012

Group By then Concatenate strings

Hi There,
is it possible to Concatenate strings using group by
Select Concatenate (Name) from table1 group by dept
Thanks
GaneshHi, Ganesh
See: http://www.aspfaq.com/show.asp?id=2529
Razvan|||Ganesh
Please tell us what is the result ?
CREATE TABLE #test
(
FirstName VARCHAR(100) NOT NULL,
LastName VARCHAR(100) NOT NULL,
Dept INT
)
INSERT INTO #test VALUES ('Bill','Smith',100)
INSERT INTO #test VALUES ('John','Lee',100)
INSERT INTO #test VALUES ('David','Litvak',200)
INSERT INTO #test VALUES ('Alex','Boon',200)
SELECT * ,FirstName+' '+LastName AS SurName
FROM #test
"Ganesh" <ganeshsankaran@.hotmail.com> wrote in message
news:C222CA3D-346A-4A95-AB33-4EDA626E7B9A@.microsoft.com...
> Hi There,
> is it possible to Concatenate strings using group by
> Select Concatenate (Name) from table1 group by dept
> --
> Thanks
> Ganesh

Wednesday, March 7, 2012

Group by on a concatenate field

Select TOP 100 CONVERT(VarChar(10),Service_Prefix)+ '' + CONVERT(VarChar(10),Service_Code) as CODE, Date_Issued, sum(Amount)
from dbo.Enterprise_Credits_Import_90_days
where CONVERT(VarChar(10),Service_Prefix)+ '' + CONVERT(VarChar(10),Service_Code) <> ' 0' and Service_Prefix like 'F'
Group by ?

How can I group by the field that I selected as CODE?

you have to repeat the expression:

Select TOP 100 CONVERT(VarChar(10),Service_Prefix)+ '' + CONVERT(VarChar(10),Service_Code) as CODE, Date_Issued, sum(Amount)
from dbo.Enterprise_Credits_Import_90_days
where CONVERT(VarChar(10),Service_Prefix)+ '' + CONVERT(VarChar(10),Service_Code) <> ' 0' and Service_Prefix like 'F'
Group by CONVERT(VarChar(10),Service_Prefix)+ '' + CONVERT(VarChar(10),Service_Code), Date_Issued

|||Or if you're interested in readability you could make it:

select top 100 code, date_issued, sum(amount)
from
(select CONVERT(VarChar(10),Service_Prefix)+ '' + CONVERT(VarChar(10),Service_Code) as CODE, Date_Issued, Amount, Service_Prefix from
dbo.Enterprise_Credits_Import_90_days) c
where code <> '0'
and Service_Prefix like 'F'
group by code, date_issued

But... why do you add an empty string in between? And do you mean LIKE 'F%', rather than LIKE 'F' ?

Don't underestimate the power of table expressions. The optimiser knows what you mean (so there's very little difference to performance), and you can easily make something far more readable that way. You could also have used a CTE, like this:

with c as (select CONVERT(VarChar(10),Service_Prefix)+ '' +

CONVERT(VarChar(10),Service_Code) as CODE, Date_Issued, Amount,

Service_Prefix from

dbo.Enterprise_Credits_Import_90_days)
select top 100 code, date_issued, sum(amount)

from c
where code <> '0'

and Service_Prefix like 'F'

group by code, date_issued

Rob|||

Rob Farley wrote:

Or if you're interested in readability you could make it:

select top 100 code, date_issued, sum(amount)
from
(select CONVERT(VarChar(10),Service_Prefix)+ '' + CONVERT(VarChar(10),Service_Code) as CODE, Date_Issued, Amount, Service_Prefix from
dbo.Enterprise_Credits_Import_90_days) c
where code <> '0'
and Service_Prefix like 'F'
group by code, date_issued

SQL Server does not allow grouping by column alias names - does it? Other RDB engines allow this, and even ordinal grouping (group by 1,2, ...) notations but I thought SQL Server required you to repeat the expressions.

|||But this isn't actually grouping by a column alias. It's grouping by a field in a table expression. It would be no different if you created a view which had those fields in it - then you wouldn't see a problem using the view's fields to group by...

By wrapping the fields up in a table expression, you can easily circumnavigate the restrictions on SQL Server to repeat those expressions.

Rob|||right - I should have looked more closely at your original query - I didn't see the inline view before...|||:) So has it helped?|||

Im going to test it today. Ill let you know if I get it to work.

Thanks for alll the help !

|||

I tried the first statement and was able to make it work. Thanks for the info.

The second query gave me this error

Server: Msg 156, Level 15, State 1, Line 1
Incorrect syntax near the keyword 'with'.

Also due to the fact that the database has around 6 million records the group by's seem to make the query take a while to run. Is there any way to speed up the query?

Thanks again for your help

|||The second one requires SQL2005 - you'll get an error in SQL2000.

Could you get away with grouping by service_prefix and service_code separately, and then only concatenating them in the final select? That way, you could put a useful index on those two fields (plus date_issued, and amount), and it should run much more nicely. A covering index which includes all the fields you're interested in will mean that it doesn't even need to look at the table, because all the info will exist in the index.

Like this:

Select TOP 100 CONVERT(VarChar(10),Service_Prefix)+ '' + CONVERT(VarChar(10),Service_Code) as CODE, Date_Issued, sum(Amount)
from dbo.Enterprise_Credits_Import_90_days
where Service_Code <> ' 0' and Service_Prefix like 'F%'
group by service_code, service_prefix, date_issued

And you have an index on service_code, service_prefix, date_issued, amount

By changing the where clause to filter on the service_code rather than the concatenated field, that will help performance too, because it can then use the index more effectively. If you need to cater for where the 0 can be either in the prefix or in the code, you could always do an extra check... but try to avoid grouping or filtering on calculated fields, which makes it harder for the system to use indexes.

Rob|||

I think I see what you are saying here. The group by on both non concatenated fields should produce the same results as one group by by using the indexes more effectively. Ill try this and let you know. Prob be tommorow. Although in order to do a group by I thought you had to have the the group by fields in the select statement?

Thanks for your help.

|||You don't need to have the group by fields in the select statement, you just can't use fields that aren't either aggregated or one of the grouped fields.

But you can certainly select a concatenation of two of the grouped fields - definitely no problem there.

Rob|||

I would be careful about grouping on such a value as this:

Group by CONVERT(VarChar(10),Service_Prefix)+ '' + CONVERT(VarChar(10),Service_Code), Date_Issued

Instead of doing all of this conversion stuff in the bowels of the query do it either:

1. In the user interface and write the query as:

Select TOP 100 Service_Prefix, Service_Code, Date_Issued, sum(Amount)
from dbo.Enterprise_Credits_Import_90_days
where Service_Code<> '0'
and Service_Prefix = 'F'
Group by Service_Prefix, Service_Code, Date_Issued

2. If you cannot use the UI, then do the conversion in an aggregate. There will be little performance hit because there will only be a single row in every case:

Select TOP 100 Max(CONVERT(VarChar(10),Service_Prefix)+ '' + CONVERT(VarChar(10),Service_Code)) as CODE,
Date_Issued, sum(Amount)
from dbo.Enterprise_Credits_Import_90_days
where Service_Code<> '0'
and Service_Prefix = 'F'
Group by Service_Prefix, Service_Code, Date_Issued

ANY code appearing in an expression in a where or group by clause (and having, join-on criteria, etc) can cause performance issues that cannot be solved with indexes, like the criteria:

CONVERT(VarChar(10),Service_Prefix)+ '' + CONVERT(VarChar(10),Service_Code) <> ' 0'

Will not perform well because you don't have an index on this expression, and the optimizer would have to figure it out over and over instead of a simple probe into an index.

|||Yes... this is the point I was trying to make.

One thing to do it as an intellectual exercise about what you can do with T-SQL, but as soon as you're talking about performance, then you need to consider the fact that you really don't want to use the results of functions for filters/groups/sorts.

Rob|||Not disagreeing with you...Just adding my 2 cents worth to clarify/back you up :)