0

Suppose I have three tables: STORES, STATES, and STORES_STATES.

  • STORES contains records of individual stores
  • STATES just contains a list of all 50 US states
  • STORES_STATES is a join table that contains pairs of stores and states to show which stores are available in which states

Consider the following tables (can't figure out how to format an ASCII table here):

table screenshot

What I need is a SELECT statement that will return each store in one column, and a list of states in another:

table screenshot

How do I combine the results of a subquery into a single column like this?

I would imagine it would be similar to this query:

SELECT
  STORE_NAME,
  (SELECT STATE_ABV FROM STORES_STATES WHERE STORES_STATES.STORE_ID = STORES.ID)
FROM STORES;

But this obviously fails since the subquery returns more than one result.

Zephyr
  • 9,885
  • 4
  • 28
  • 63

3 Answers3

0

You can use APPLY :

SELECT s.store_name, STUFF(ss.state_abv, 1, 1, '') AS States
FROM stores s CROSS APPLY
     ( SELECT ', '+ss.state_abv
       FROM stores_state ss
       WHERE ss.store_id = s.id
       FOR XML PATH('')
     ) ss(state_abv);
Yogesh Sharma
  • 49,870
  • 5
  • 26
  • 52
0

your two options are either the STRING_AGG function in the newest versions of SQL Server, or using an XML concatenation technique as described in this answer:

How to concatenate text from multiple rows into a single text string in SQL server?

The XML method is messy-looking in your code and difficult to remember - I always have to look up the syntax - but it's actually quite fast.

Russell Fox
  • 5,273
  • 1
  • 24
  • 28
0

You can use STUFF() function along side with FOR XML PATH('') and join both tables on StoreID

CREATE TABLE Stores
(
  ID INT,
  StoreName VARCHAR(45)
);

CREATE TABLE States
(
  StoreID INT,
  StateABV VARCHAR(45)
);

INSERT INTO Stores VALUES
(1, 'Wolmart'), (2, 'Costco'), (3, 'Croegers');

INSERT INTO States VALUES
(1, 'NY'), 
(1, 'WY'),
(1, 'MI'),
(2, 'AL'),
(2, 'GA'),
(2, 'TX'),
(3, 'FL');

SELECT SR.StoreName,
       STUFF(
              (
                SELECT ',' + ST.StateABV
                FROM States ST
                WHERE ST.StoreID = SR.ID
                FOR XML PATH('')
              ), 1, 1, ''
           ) State
FROM Stores SR;

Returns:

+-----------+----------+
| StoreName |  State   |
+-----------+----------+
| Wolmart   | NY,WY,MI |
| Costco    | AL,GA,TX |
| Croegers  | FL       |
+-----------+----------+
Ilyes
  • 14,640
  • 4
  • 29
  • 55