-1

following situation, pos/neg_text are repeating:

This is my feedback table:

id  text-id    pos_text         neg_text       cat_id
1   1          nice people      null           21 
2   1          nice people      null           24 
3   1          nice people      null           27 
4   1          null             cold room      36
5   1          null             cold room      37

I would like to bring all these data into a single row like:

id  text-id    pos_text         neg_text       pos_cat_id       neg_cat_id
1   1          nice people      cold room      "21,24,27"       "36,37"   

How should my SQL query look like? I am implementing an algorithm with TypeScript in my middleware to solve this problem, and maybe there are DB-specialists can solve that much more elegant with a simple SQL-Query.

Using SQL Server 2008

Lonely
  • 6,926
  • 8
  • 43
  • 81
  • 1
    What have you tried so far? Why didn't it work? Or what existing solutions have you looked at, and what didn't you understand about them? – Larnu Aug 28 '20 at 09:12
  • which version of sql-server you are using? – Fahmi Aug 28 '20 at 09:12
  • 1
    What happened to `'onice people'` too? – Larnu Aug 28 '20 at 09:13
  • @Fahmi MSSQL Server 2008, thank you – Lonely Aug 28 '20 at 09:13
  • 1
    2008 has been completely unsupported for over a year now, you should really be looking at upgrade paths, if not already (some time ago). – Larnu Aug 28 '20 at 09:14
  • typo corrected ;) – Lonely Aug 28 '20 at 09:15
  • @Lonely you really, really should upgrade. If you used SQL Server 2017 (latest version is 2019) you could use a single `GROUP BY` with eg `STRING_AGG`. The earliest SQL Server version still in mainstream support is 2014 – Panagiotis Kanavos Aug 28 '20 at 09:18
  • you all have right, sorry I've added the correct versions, – Lonely Aug 28 '20 at 09:19
  • 1
    @Lonely the versions you posted have nothing to do with the *server*, they're the components of SSMS, a client administration tool – Panagiotis Kanavos Aug 28 '20 at 09:19
  • That "version" is your SSMS details; it has nothing to do with SQL Server's version. We still really would like to see those attempt/research you did too. – Larnu Aug 28 '20 at 09:19
  • @Lonely if you search how to aggregate/concatenate strings in older versions of SQL Server you'll find a lot of duplicates that typically use `FOR XML` and some string manipulations to "concatenate" strings – Panagiotis Kanavos Aug 28 '20 at 09:20
  • @PanagiotisKanavos I'm not a SQL-Database specialist, I am TypeScript-Developer :) How can I get the version in this case? (I normally do NoSQL ) – Lonely Aug 28 '20 at 09:21
  • https://stackoverflow.com/questions/451415/simulating-group-concat-mysql-function-in-microsoft-sql-server-2005 – a_horse_with_no_name Aug 28 '20 at 09:21
  • @Lonely by reading the docs? Googling how to retrieve the SQL Server version? Checking the version displayed in SSMS? You're asking people to serve you a solution, not really trying, or providing the necessary information. You need to read the docs in NoSQL databases too - even more so than SQL databases as each product is completely different from others – Panagiotis Kanavos Aug 28 '20 at 09:22
  • If that is not an easy question, please ignore, I'll transform that in TypeScript. I've no intentions to be a SQL-specialist ;) – Lonely Aug 28 '20 at 09:25

1 Answers1

1

Due to the use of such an old version of SQL Server, this is not easy. You lack simple tools like CONCAT, for implicit conversion, and more recent functions like STRING_AGG, meaning you need to use 3 scans of the table to achieve what could be done in 1 scan.

Instead we need to use the "Old " FOR XML PATH method here to aggregate the values, and the use CONVERT rather than a simple CONCAT(',',sq.catid). I've used 3 as the length, but you likely need something longer.

WITH YourTable AS(
    SELECT *
    FROM (VALUES(1,1,'nice people',null,21), 
                (2,1,'nice people',null,24), 
                (3,1,'nice people',null,27), 
                (4,1,null,'cold room',36),
                (5,1,null,'cold room',37))V(id,textid,postext,negtext,catid))
SELECT MIN(ID) AS ID,
       textid,
       MAX(postext) AS postext,
       MAX(negtext) AS negtext,
       STUFF((SELECT ',' + CONVERT(varchar(3),sq.catid)
              FROM YourTable sq
              WHERE sq.textid = YT.textid
                AND sq.postext IS NOT NULL
              ORDER BY sq.id
              FOR XML PATH(''),TYPE).value('(./text())[1]','varchar(MAX)'),1,1,'') AS poscatid,
       STUFF((SELECT ',' + CONVERT(varchar(3),sq.catid)
              FROM YourTable sq
              WHERE sq.textid = YT.textid
                AND sq.negtext IS NOT NULL
              ORDER BY sq.id
              FOR XML PATH(''),TYPE).value('(./text())[1]','varchar(MAX)'),1,1,'') AS negtextid
FROM YourTable YT
GROUP BY YT.textid;

db<>fiddle

As a note, this is how simple it is on more recent versions of SQL:

SELECT MIN(ID) AS ID,
       textid,
       MAX(postext) AS postext,
       MAX(negtext) AS negtext,
       STRING_AGG(CASE WHEN postext IS NOT NULL THEN catid END,',') WITHIN GROUP (ORDER BY ID) AS poscatid,
       STRING_AGG(CASE WHEN negtext IS NOT NULL THEN catid END,',') WITHIN GROUP (ORDER BY ID) AS negcatid
FROM YourTable
GROUP BY textid;
Larnu
  • 76,706
  • 10
  • 34
  • 63
  • non of them works, I've implemented a typescript version :/ – Lonely Aug 28 '20 at 10:09
  • *"non of them works*" I dispute that, @Lonely. [db<>fiddle](https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=e9cf56e6b7fb5a0e295a046f0fc5dcb8). What does "not work" mean? – Larnu Aug 28 '20 at 10:13
  • maybe you're right but thank you, I won't invest more time because I've already implemented it in TypeScript. I've tried to delete my question, couldn't because there is an answer. I don't want to irritate future-visitors. – Lonely Aug 28 '20 at 10:19
  • Deleting questions which users have put their time and effort into answering irritates users more, @Lonely . – Larnu Aug 28 '20 at 10:20
  • Dear @Larnu, can you please recommend me a SQL-book teaches me SQL-queries like above? Thank you very much,.. – Lonely Aug 29 '20 at 11:16
  • Book recommendations isn't for SO is for, @Lonely , however, I've never read a book on SQL (I'm entirely self taught) so I can't really suggest anything for you I'm afraid. – Larnu Aug 29 '20 at 11:25