我正在使用 Sybase ASE 数据库 我有两个看起来像的表:
表Shops
:
---------------------
| ShopName | ShopID |
---------------------
| Sweetie | 1 |
| Candie | 2 |
| Sugarie | 3 |
---------------------
表Sweets
:
----------------------
| SweetName | ShopID |
----------------------
| lolly | 1 |
| redlolly | 1 |
| greenloly | 1 |
| taffy | 2 |
| redtaffy | 2 |
| bluetaffy | 2 |
| choco | 3 |
| mintchoco | 3 |
| milkchoco | 3 |
| gummybees | 3 |
----------------------
我想编写一个生成如下结果的查询:
-----------------------------------------------------
| ShopName | Sweets |
-----------------------------------------------------
| Sweetie | lolly, redlolly, greenlolly |
| Candie | taffy, redtaffy, bluetaffy |
| Sugarie | choco, mintchoco, milkchoco, gummybees |
-----------------------------------------------------
我应该怎么做呢?我需要这个用于Sybase ASE数据库。我尝试了LIST()
函数,但是我收到了错误。我检查了它的文档,结果证明,ASE版本中没有这个功能。
这可能意味着会涉及一些“动态sql”(我很少知道这意味着什么)。有人可以帮忙吗?
我可能希望ShopId
代替结果表中的ShopName
...我还不确定。我想这不会有太大区别。此外,Sweets
列结果中的尾随逗号不是问题。我想要的只是一个非空白分隔符。
答案 0 :(得分:5)
您必须指定您正在使用的DBMS。
MySQL的GROUP CONCAT正是您所需要的。
SELECT ShopName, GROUP_CONCAT(SweetName SEPARATOR ", ")
FROM Shops a
JOIN Sweets b
ON a.ShopID = b.ShopID
GROUP BY ShopName
答案 1 :(得分:2)
这是一个交叉表查询,在一次查询中无法使用Sybase ASE。
您可以使用临时表创建存储过程,用光标填充它,然后从此临时表中选择。
答案 2 :(得分:1)
我在SQL Server上对此进行了测试,但希望它也适用于Sybase。如果没有,也许它会让你足够接近解决它。
如果我创建此功能:
CREATE FUNCTION SweetsList(@shopID int)
RETURNS varchar(500)
AS
BEGIN
DECLARE @list varchar(500)
SELECT @list = COALESCE(@list+', ','') + SweetName
FROM Sweets
WHERE ShopID = @shopID
RETURN @list
END
然后我可以执行此查询并获得您想要的结果:
SELECT ShopName, dbo.SweetsList(ShopID) AS Sweets
FROM Shops
希望这有帮助。
答案 3 :(得分:1)
不幸的是,adrift's回答中的方法不适用于Sybase ASE的select语句,变量@list不会为每一行更新,它仅适用于最后一行。但是因为每行的更新执行并且表的大小不大,所以可以使用update语句来执行。小例子:
declare @list varchar(500)
update Sweets
set @list = @list + SweetName + ', '
where ShopID = 1
select SUBSTRING(@list, 1, Len(@list) - 2)
P.S。至于我,光标不是好方法......
答案 4 :(得分:0)
适用于Sybase ASE ...
CREATE FUNCTION SweetsList(@SN varchar(10))
returns varchar(255)
AS
DECLARE @SwNList varchar(255)
DECLARE @FetchSwN varchar(55)
DECLARE @Status INT, @Error INT
DECLARE ListCurs CURSOR FOR
SELECT SweetName
FROM Sweets AS SW
JOIN Shops AS SH
ON SH.ShopID = SW.ShopID
WHERE SH.ShopName = @SN
FOR READ ONLY
OPEN ListCurs
SELECT @Status = 0
WHILE @Status = 0
BEGIN
FETCH ListCurs INTO @FetchSwN
SELECT @Status = @@SQLSTATUS
IF @Status = 0
BEGIN
SELECT @SwNList = CASE WHEN @SwNList IS NULL THEN '' ELSE @SwNList + ', ' END + @FetchSwN
END
END
CLOSE ListCurs
RETURN (@SwNList)
go
然后执行......
SELECT ShopName, dbo.SweetsList(ShopName) AS Sweets FROM Shops