如何用其他表中的列表填充列?

时间:2018-10-29 17:30:16

标签: sql sql-server

假设我有三个表:STORESSTATESSTORES_STATES

  • STORES 包含各个商店的记录
  • STATES 仅包含美国所有50个州的列表
  • STORES_STATES 是一个联接表,其中包含成对的存储和状态,以显示哪些存储在哪些状态可用。

请考虑以下表格(在这里无法弄清楚如何格式化ASCII表):

table screenshot

我需要的是一条SELECT语句,它将在一个列中返回每个存储,而在另一列中返回一个状态列表:

table screenshot

如何将子查询的结果合并到这样的单个列中?

我想这将与以下查询类似:

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

但这显然失败了,因为子查询返回了多个结果。

3 个答案:

答案 0 :(得分:0)

您可以使用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);

答案 1 :(得分:0)

您的两个选项要么是最新版本的SQL Server中的STRING_AGG函数,要么使用此答案中所述的XML串联技术:

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

XML方法在您的代码中看起来很凌乱,而且很难记住-我总是必须查找语法-但这实际上非常快。

答案 2 :(得分:0)

您可以将STUFF()函数与FOR XML PATH('')一起使用,并在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;

返回:

+-----------+----------+
| StoreName |  State   |
+-----------+----------+
| Wolmart   | NY,WY,MI |
| Costco    | AL,GA,TX |
| Croegers  | FL       |
+-----------+----------+