首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Server 2008 -查找艺术品的位置

Server 2008 -查找艺术品的位置
EN

Stack Overflow用户
提问于 2017-03-02 21:35:15
回答 1查看 59关注 0票数 2

请考虑Server 2008数据库中的下表和数据:

代码语言:javascript
复制
CREATE TABLE sponsorships 
(
    sponsorshipID INT NOT NULL PRIMARY KEY IDENTITY,
    sponsorshipLocationID INT NOT NULL,
    sponsorshipArtworkID INT NOT NULL
);

INSERT INTO sponsorships (sponsorshipLocationID, sponsorshipArtworkID) 
VALUES (1, 1);
INSERT INTO sponsorships (sponsorshipLocationID, sponsorshipArtworkID) 
VALUES (1, 2);
INSERT INTO sponsorships (sponsorshipLocationID, sponsorshipArtworkID) 
VALUES (2, 1);
INSERT INTO sponsorships (sponsorshipLocationID, sponsorshipArtworkID) 
VALUES (2, 2);
INSERT INTO sponsorships (sponsorshipLocationID, sponsorshipArtworkID) 
VALUES (3, 3);
INSERT INTO sponsorships (sponsorshipLocationID, sponsorshipArtworkID) 
VALUES (4, 3);
INSERT INTO sponsorships (sponsorshipLocationID, sponsorshipArtworkID) 
VALUES (5, 4);
INSERT INTO sponsorships (sponsorshipLocationID, sponsorshipArtworkID) 
VALUES (6, 1);
INSERT INTO sponsorships (sponsorshipLocationID, sponsorshipArtworkID) 
VALUES (7, 1);
INSERT INTO sponsorships (sponsorshipLocationID, sponsorshipArtworkID) 
VALUES (7, 3);

SELECT *
FROM sponsorships s
ORDER BY s.sponsorshipLocationID, s.sponsorshipArtworkID

如何产生以下输出?

代码语言:javascript
复制
CREATE TABLE sponGroups 
(
    rank INT,
    sponsorshipID INT,
    sponsorshipLocationID INT,
    sponsorshipArtworkID INT
);

INSERT INTO sponGroups VALUES (1, 1, 1, 1);
INSERT INTO sponGroups VALUES (1, 2, 1, 2);
INSERT INTO sponGroups VALUES (1, 3, 2, 1);
INSERT INTO sponGroups VALUES (1, 4, 2, 2);
INSERT INTO sponGroups VALUES (2, 5, 3, 3);
INSERT INTO sponGroups VALUES (2, 6, 4, 3);
INSERT INTO sponGroups VALUES (3, 7, 5, 4);
INSERT INTO sponGroups VALUES (4, 8, 6, 1);
INSERT INTO sponGroups VALUES (5, 9, 7, 1);
INSERT INTO sponGroups VALUES (5, 10, 7, 3);

SELECT *
FROM sponGroups sg
ORDER BY sg.rank, sg.sponsorshipID, sg.sponsorshipLocationID, sg.sponsorshipArtworkID

提供小提琴,这里

解释

艺术品在不同的地方展出。有些地点安装了双面艺术品(如窗户),有些地方则安装了单面艺术品(如墙壁)。例如,位置1的艺术品是双面的-它有赞助artwork 1和2-在位置5 (sponsorshipArtworkID 4)有单面的艺术品。

为了打印和安装的目的,我需要一个查询,以产生每件艺术品,无论是一面或两个,以及所有的位置与该作品。(请参考上面链接的小提琴中所需的输出。)例如,我需要告诉打印机:

  • 打印双面艺术作品(1,2),并安装在位置(1,2);
  • 打印单面艺术品(3),并安装在位置(3,4);
  • 打印单面艺术品(4)并安装在位置(5);
  • 打印单面艺术品(1)并安装在位置(6);
  • 打印双面艺术作品(1,3),并安装在位置(7)。

请注意,art有时会被重用,因此sponsorshipArtworkID 1在单面和双面位置都被使用.

我尝试使用DENSE_RANK(),一种递归的CTE,并按设置分治来解决这个问题,但到目前为止还未能解决。提前谢谢你的帮助。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-03-03 01:06:08

它可能看起来有点难看,但想法很简单。

首先由sponsorshipLocationID组成组,并使用关联的sponsorshipArtworkID列表构建一个逗号分隔的字符串。

然后根据这个以逗号分隔的艺术品ID字符串计算密集等级。

在下面的查询中,我使用FOR XML连接字符串。这不是唯一的办法。有好的,快速的CLR函数写的,做它。

我建议一步一步地运行下面的查询,并检查中间结果以了解它是如何工作的。

样本数据

代码语言:javascript
复制
DECLARE @sponsorships TABLE
(
    sponsorshipID INT NOT NULL PRIMARY KEY IDENTITY,
    sponsorshipLocationID INT NOT NULL,
    sponsorshipArtworkID INT NOT NULL
);

INSERT INTO @sponsorships (sponsorshipLocationID, sponsorshipArtworkID) VALUES 
(1, 1),
(1, 2),
(2, 1),
(2, 2),
(3, 3),
(4, 3),
(5, 4),
(6, 1),
(7, 1),
(7, 3);

查询

代码语言:javascript
复制
WITH
CTE_Locations
AS
(
    SELECT
        sponsorshipLocationID
    FROM
        @sponsorships AS S
    GROUP BY
        sponsorshipLocationID
)
,CTE_Artworks
AS
(
    SELECT
        CTE_Locations.sponsorshipLocationID
        ,CA_Data.Artwork_Value
    FROM
        CTE_Locations
        CROSS APPLY
        (
            SELECT CAST(S.sponsorshipArtworkID AS varchar(10)) + ','
            FROM
                @sponsorships AS S
            WHERE
                S.sponsorshipLocationID = CTE_Locations.sponsorshipLocationID
            ORDER BY
                S.sponsorshipArtworkID
            FOR XML PATH(''), TYPE
        ) AS CA_XML(XML_Value)
        CROSS APPLY
        (
            SELECT CA_XML.XML_Value.value('.', 'NVARCHAR(MAX)')
        ) AS CA_Data(Artwork_Value)
)
,CTE_Rank
AS
(
    SELECT
        sponsorshipLocationID
        ,Artwork_Value
        ,DENSE_RANK() OVER (ORDER BY Artwork_Value) AS r
    FROM CTE_Artworks
)
SELECT
    CTE_Rank.r
    ,S.sponsorshipID
    ,CTE_Rank.sponsorshipLocationID
    ,S.sponsorshipArtworkID
FROM
    CTE_Rank
    INNER JOIN @sponsorships AS S 
        ON S.sponsorshipLocationID = CTE_Rank.sponsorshipLocationID
ORDER BY
    S.sponsorshipID
;

结果

代码语言:javascript
复制
+---+---------------+-----------------------+----------------------+
| r | sponsorshipID | sponsorshipLocationID | sponsorshipArtworkID |
+---+---------------+-----------------------+----------------------+
| 2 |             1 |                     1 |                    1 |
| 2 |             2 |                     1 |                    2 |
| 2 |             3 |                     2 |                    1 |
| 2 |             4 |                     2 |                    2 |
| 4 |             5 |                     3 |                    3 |
| 4 |             6 |                     4 |                    3 |
| 5 |             7 |                     5 |                    4 |
| 1 |             8 |                     6 |                    1 |
| 3 |             9 |                     7 |                    1 |
| 3 |            10 |                     7 |                    3 |
+---+---------------+-----------------------+----------------------+

秩的实际值与预期结果不完全相同,但它们正确地对行进行了分组。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42566429

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档