选择组合子查询(pivot)中的行的语句

时间:2014-02-07 18:43:52

标签: sql-server tsql

我有:

tbl_product:
------------
product_id
name
description

tbl_user:
------------
user_id
first_name
last_name
initials

多个用户可以拥有单个产品,我通过创建表来表示:

xref_product_user: 
product_id
user_id 

构成复合主键,其中每列是其各自表的foreign_key。

由于每个产品可以有多个用户,我需要编写一个包含

的select语句
  

产品名称,描述,组合用户首字母(逗号分隔的字符串)。

我们假设我有一个产品巧克力,由用户迈克拥有 约翰逊丹威廉姆斯。那么我的结果应该是

NAME        DESCRIPTION    INTIALS
chocolate   candy          mj, dw

由于首字母部分,我似乎无法弄清楚如何编写这个select语句。有人有什么想法吗?

4 个答案:

答案 0 :(得分:1)

一个函数可能是一个很好的,易于维护的方法来处理它:

CREATE FUNCTION [dbo].[fn_GetInitialsForProduct]
(
    @product_id
)
RETURNS varchar(200)
AS
BEGIN
    declare @Initials varchar(200)

    set @Initials = ''

    select @Initials=@Initials + ', ' + isnull(u.Initials, '')
    from dbo.tbl_user u
    inner join dbo.xref_product_user x
    on u.user_id = x.user_id
    where x.product_id = @product_id
    order by u.Initials

    if left(@Initials, 2) = ', '
        set @Initials = substring(@Initials, 3, len(@Initials) - 2)

    return @Initials
END

--AND HERE'S HOW TO CALL IT

select p.name, p.description, dbo.GetInitialsForProduct(p.product_id) as Initials
from tbl_product p

答案 1 :(得分:0)

这个怎么样?无需存储过程。

    create table #product (product_id int, name nvarchar(50), description nvarchar(50))
create table #user(user_id int, initials nvarchar(50))
Create table #xref_product_user (product_id int, user_id int)

insert into #product values (1,'chocolate','candy')
insert into #product values (2,'shrimp','seafood')
insert into #user values (1, 'mj')
insert into #user values (2, 'dw')
insert into #xref_product_user values (1,1)
insert into #xref_product_user values (1,2)
insert into #xref_product_user values (2,2)


SELECT p.*,
    STUFF((
            SELECT ', ' + initials
            FROM #user u
            INNER JOIN #xref_product_user x ON x.user_id = u.user_id AND x.product_id = p.product_id
            FOR XML path('')
            ), 1, 2, '') [INTIALS]
FROM #product p




drop table #product, #user, #xref_product_user

答案 2 :(得分:0)

测试数据

DECLARE @tbl_product TABLE(product_id INT,name VARCHAR(10),[description] VARCHAR(20))
INSERT INTO @tbl_product VALUES
(1,'Name 1','description 1'),(2,'Name 2','description 2'),(3,'Name 3','description 3')

DECLARE @tbl_user TABLE([user_id] INT,first_name VARCHAR(10)
                       ,last_name VARCHAR(10),initials VARCHAR(10))
INSERT INTO @tbl_user VALUES
(1,'f_name 1','l_name 1','i1'),(2,'f_name 2','l_name 2','i2'),
(3,'f_name 3','l_name 3','i3')

DECLARE @xref_product_user TABLE(product_id INT,[user_id] INT)
INSERT INTO @xref_product_user VALUES
(1, 1), (1, 2), (1, 3),
(2, 1), (2, 2),
(3, 3)

查询1

SELECT  P.Name 
       ,P.[description]
       ,STUFF((SELECT ', ' + U.initials
               FROM @tbl_user u INNER JOIN @xref_product_user UP
               ON U.[user_id] = UP.[user_id]
               WHERE UP.product_id = P.product_id
               FOR XML PATH(''), TYPE)
               .value('.','NVARCHAR(MAX)'),1,2,'') AS InitialsList
FROM @tbl_product P

查询2

使用CROSS APPLY

SELECT DISTINCT  
        P.Name 
       ,P.[description]
       ,STUFF(L.Initials, 1, 2,'') AS Initials
FROM @tbl_product P
         CROSS APPLY
            (
             SELECT ', ' + U.initials [text()]
             FROM @tbl_user u INNER JOIN @xref_product_user UP
             ON U.[user_id] = UP.[user_id]
             WHERE UP.product_id = P.product_id
             FOR XML PATH('')
             )L(Initials)

结果集

╔════════╦═══════════════╦══════════════╗
║  Name  ║  description  ║ InitialsList ║
╠════════╬═══════════════╬══════════════╣
║ Name 1 ║ description 1 ║ i1, i2, i3   ║
║ Name 2 ║ description 2 ║ i1, i2       ║
║ Name 3 ║ description 3 ║ i3           ║
╚════════╩═══════════════╩══════════════╝

请参阅此处 SQL Fiddle

答案 3 :(得分:0)

你走了。

使用SQL小提琴:http://sqlfiddle.com/#!3/8793d/3

SQL语句

SELECT  p.name 
       ,p.[description]
       ,Initials = 
          STUFF(
            (  SELECT ', ' + u.initials
               FROM tbl_user u INNER JOIN xref_product_user pux
                   ON u.user_id = pux.user_id
                   AND pux.product_id = p.product_id
               FOR XML PATH(''), TYPE)
               .value('.','NVARCHAR(MAX)'),1,2,'')
FROM tbl_product p

样本数据的结果

NAME            DESCRIPTION             INITIALS
Twinkies        Sugary Snack            fm
Chocolate       Candy                   mj, dw
Glazed Donuts   High calorie Breakfast  (null)