以逗号分隔列表形式返回 SQL 数据

发布于 2024-10-08 17:05:13 字数 985 浏览 2 评论 0原文

这是我的表:

-----------------------------------------
Hotels
-----------------------------------------
HotelID | HotelName
-----------------------------------------


-----------------------------------------
HotelImages
-----------------------------------------
HotelImageID | HotelID | Filename
-----------------------------------------

我想创建一个 SELECT 语句来返回数据,如下所示:

HotelID | HotelName | Images
-----------------------------------------
1 | Hotel1 | Image1,Image2,Image3
2 | Hotel2 | Image4,Image5,Image6

如何修改我的查询来执行此操作?我有:

SELECT H.HotelID, H.HotelName, '' AS Images
FROM Hotels H

我知道我可以使用 COALESCE 创建一个逗号分隔的列表:

DECLARE @Images varchar(500)
SELECT @Images = COALESCE(@Images + ',', '') + CAST(Filename AS varchar(100)) FROM HotelImages WHERE HotelID = 1
SELECT @Images

但我不知道如何将其集成到我当前的查询中,以便可以将列表与其余的酒店数据一起返回。

我应该提到我正在使用 SQL Server 2000。

Here are my tables:

-----------------------------------------
Hotels
-----------------------------------------
HotelID | HotelName
-----------------------------------------


-----------------------------------------
HotelImages
-----------------------------------------
HotelImageID | HotelID | Filename
-----------------------------------------

I'd like to create a SELECT statement that will return the data like so:

HotelID | HotelName | Images
-----------------------------------------
1 | Hotel1 | Image1,Image2,Image3
2 | Hotel2 | Image4,Image5,Image6

How can I modify my query to do this? I have:

SELECT H.HotelID, H.HotelName, '' AS Images
FROM Hotels H

I know I can use COALESCE to create a comma-delimited list:

DECLARE @Images varchar(500)
SELECT @Images = COALESCE(@Images + ',', '') + CAST(Filename AS varchar(100)) FROM HotelImages WHERE HotelID = 1
SELECT @Images

But I don't know how to integrate that into my current query so that the list can be returned with the rest of the hotel data.

I should mention I'm using SQL Server 2000.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一个人练习一个人 2024-10-15 17:05:13

由于这是 SQL 2000,因此您的选择有些有限。您不能使用 FOR XML PATH 或递归 CTE。

此外,COALESCE 技巧仅适用于填充单个酒店的逗号分隔列表。不是全部。

老实说,您最好在客户端中执行此操作。但如果无法做到这一点(想到某些不得命名的报告应用程序),您可以执行以下操作。

请注意,循环过程的次数等于与酒店关联的最大文件数。这比为每个酒店设置一个循环(例如,从 select 子句调用 UDF)要好得多。

DECLARE @foo table ( HotelID int , lastID int , FileNameList varchar(8000))

INSERT INTO @Foo 

SELECT
    start.HotelID,
    start.firstID ,
    id.FileName 

FROM
    (SELECT 
        HotelID,
        min(HotelImageID ) firstID
    from 
        HotelImages


    group by HotelID) start
    INNER JOIN HotelImages hi
    ON start.firstID = hi.HotelImageID 


WHILE @@RowCount <> 0 
BEGIN

    UPDATE @foo
    SET 
        FileNameList = FileNameList + ',' + FileName
        lastID  = Xnext.nextID
    FROM 
        @foo f
        INNER JOIN HotelImages hi
        ON f.HotelID = id.HotelID
        INNER JOIN 
        (SELECT 

            id.HotelID,
            min(HotelImageID ) nextID
        from HotelImages hi
              inner join @foo f
              on f.HotelID = id.HotelID
        where id.HotelImageID  > f.lastid


        group by id.HotelID) Xnext

        ON Xnext.nextID = id.HotelImageID 



END 

SELECT 
    h.HotelID 
    h.HotelName,
    f.FileNameList
FROM
    Hotels h
    INNER JOIN @foo f
    ON h.hotelId = f.HotelId

Since this is SQL 2000 you options are somewhat limited. You can't use FOR XML PATH or recursive CTEs

Also the COALESCE trick only works for stuffing a comma delimited list for single hotel. Not all of them.

Honestly you're better off doing this in the client. But if that can't be done (certain Report Apps that-which-must-not-be-named come to mind) you can do the following.

Note the number of times the loop process is equal to maximum number of files associated with a hotel. This is much better than setting up a loop for each hotel (e.g. calling a UDF from the select clause).

DECLARE @foo table ( HotelID int , lastID int , FileNameList varchar(8000))

INSERT INTO @Foo 

SELECT
    start.HotelID,
    start.firstID ,
    id.FileName 

FROM
    (SELECT 
        HotelID,
        min(HotelImageID ) firstID
    from 
        HotelImages


    group by HotelID) start
    INNER JOIN HotelImages hi
    ON start.firstID = hi.HotelImageID 


WHILE @@RowCount <> 0 
BEGIN

    UPDATE @foo
    SET 
        FileNameList = FileNameList + ',' + FileName
        lastID  = Xnext.nextID
    FROM 
        @foo f
        INNER JOIN HotelImages hi
        ON f.HotelID = id.HotelID
        INNER JOIN 
        (SELECT 

            id.HotelID,
            min(HotelImageID ) nextID
        from HotelImages hi
              inner join @foo f
              on f.HotelID = id.HotelID
        where id.HotelImageID  > f.lastid


        group by id.HotelID) Xnext

        ON Xnext.nextID = id.HotelImageID 



END 

SELECT 
    h.HotelID 
    h.HotelName,
    f.FileNameList
FROM
    Hotels h
    INNER JOIN @foo f
    ON h.hotelId = f.HotelId
街角迷惘 2024-10-15 17:05:13

试试这个:

SELECT H.HotelID, H.HotelName, 
Images = (select COALESCE(HotelImageID + ',', '') 
            FROM HotelImages 
            WHERE HotelID = H.id)
FROM Hotels H

try this:

SELECT H.HotelID, H.HotelName, 
Images = (select COALESCE(HotelImageID + ',', '') 
            FROM HotelImages 
            WHERE HotelID = H.id)
FROM Hotels H
尝蛊 2024-10-15 17:05:13

COALESCE 不执行您的建议。它返回列表中的第一个非 NULL 值。它不会跨行聚合值。 (尽管我同意它听起来就像是聚合)。

SQL Server 不直接支持字符串连接聚合(例如,MySQL 有 GROUP_CONCAT)。我已经看到一些提供此类功能的解决方案,但我很确定它们适用于 SQL-2005 及更高版本。 Google(或在此处搜索)“GROUP_CONCAT FOR SQL SERVER”。

COALESCE does not do what you suggest. It returns the first non-NULL value from a list. It does not aggregate values across rows. (Although I agree that it sounds like it does the aggregation).

SQL Server does not have direct support for string-concatenation aggregation (MySQL, for instance, has GROUP_CONCAT). I've seen several solutions posted that provide this kind of functionality, but I'm pretty sure they're for SQL-2005 and above. Google (or search here) on "GROUP_CONCAT FOR SQL SERVER".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文