我有一个提供 GROUP_CONCAT 的子查询。除了 LIMIT 之外,一切都很好,它没有达到我想要的效果。
这是代码:
CREATE TABLE IF NOT EXISTS Animal (
id TEXT PRIMARY KEY,
diet TEXT
);
INSERT INTO Animal VALUES ('monkey', 'herbivore');
INSERT INTO Animal VALUES ('goat', 'herbivore');
INSERT INTO Animal VALUES ('cat', 'carnivore');
INSERT INTO Animal VALUES ('dog', 'omnivore');
INSERT INTO Animal VALUES ('human', 'omnivore');
CREATE TABLE IF NOT EXISTS Domicile (
id TEXT PRIMARY KEY REFERENCES Animal,
home TEXT
);
INSERT INTO Domicile VALUES ('monkey', 'jungle');
INSERT INTO Domicile VALUES ('goat', 'farmyard');
INSERT INTO Domicile VALUES ('cat', 'house');
INSERT INTO Domicile VALUES ('dog', 'garden');
INSERT INTO Domicile VALUES ('human', 'house');
CREATE TABLE IF NOT EXISTS Food (
name TEXT PRIMARY KEY
);
INSERT INTO Food VALUES ('fruit');
INSERT INTO Food VALUES ('meat');
INSERT INTO Food VALUES ('fish');
INSERT INTO Food VALUES ('bread');
INSERT INTO Food VALUES ('sausages');
CREATE TABLE IF NOT EXISTS Eats (
id TEXT REFERENCES Animal,
name TEXT REFERENCES Food
);
INSERT INTO Eats VALUES ('monkey', 'fruit');
INSERT INTO Eats VALUES ('monkey', 'bread');
INSERT INTO Eats VALUES ('goat', 'fruit');
INSERT INTO Eats VALUES ('cat', 'meat');
INSERT INTO Eats VALUES ('cat', 'sausages');
INSERT INTO Eats VALUES ('dog', 'meat');
INSERT INTO Eats VALUES ('dog', 'bread');
INSERT INTO Eats VALUES ('dog', 'sausages');
INSERT INTO Eats VALUES ('human', 'fruit');
INSERT INTO Eats VALUES ('human', 'meat');
INSERT INTO Eats VALUES ('human', 'fish');
INSERT INTO Eats VALUES ('human', 'bread');
INSERT INTO Eats VALUES ('human', 'sausages');
.mode column
SELECT 'TEST 4: JOIN Eats using a subquery to order the names.';
SELECT Animal.id,
Animal.diet,
GROUP_CONCAT (Eats.name) as names,
Domicile.home
FROM Animal
INNER JOIN Domicile USING (id)
INNER JOIN (
SELECT * FROM Eats
ORDER BY name
) as Eats USING (id)
GROUP BY Animal.id
ORDER BY Animal.id
;
SELECT 'TEST 4 result: names in order, but not limited to 3.';
SELECT 'TEST 5: LIMIT Eats subquery to 3.';
SELECT Animal.id,
Animal.diet,
GROUP_CONCAT (Eats.name) as names,
Domicile.home
FROM Animal
INNER JOIN Domicile USING (id)
INNER JOIN (
SELECT * FROM Eats
ORDER BY name
LIMIT 3
) as Eats USING (id)
GROUP BY Animal.id
ORDER BY Animal.id
;
SELECT 'TEST 5 result: LIMIT has applied to wrong SELECT?.';
我想要的是这样的输出:
id diet names home
------ --------- ------------------- --------
cat carnivore meat,sausages house
dog omnivore bread,meat,sausages garden
goat herbivore fruit farmyard
human omnivore bread,fish,fruit house
monkey herbivore bread,fruit jungle
备注:
我从两次测试中得到的是这样的:
'TEST 4: JOIN Eats using a subquery to order the names.'
--------------------------------------------------------
TEST 4: JOIN Eats using a subquery to order the names.
id diet names home
------ --------- ------------------------------ --------
cat carnivore meat,sausages house
dog omnivore bread,meat,sausages garden
goat herbivore fruit farmyard
human omnivore bread,fish,fruit,meat,sausages house
monkey herbivore bread,fruit jungle
'TEST 4 result: names in order, but not limited to 3.'
------------------------------------------------------
TEST 4 result: names in order, but not limited to 3.
'TEST 5: LIMIT Eats subquery to 3.'
-----------------------------------
TEST 5: LIMIT Eats subquery to 3.
id diet names home
------ --------- ----- ------
dog omnivore bread garden
human omnivore bread house
monkey herbivore bread jungle
'TEST 5 result: LIMIT has applied to wrong SELECT?.'
----------------------------------------------------
TEST 5 result: LIMIT has applied to wrong SELECT?.
测试 4 和 5 的源之间的唯一区别是测试 5 子查询中的 LIMIT。
有没有办法将名称限制为 3 个元素? (我希望该限制能够轻松更改。)
我相信以下是解决方案:-
WITH
cte1 AS (
SELECT
animal.*,
domicile.home,
eats.name
FROM animal
JOIN eats ON eats.id = animal.id
JOIN domicile ON domicile.id = animal.id
ORDER BY animal.id,eats.id
),
cte2 AS (
SELECT *, (
SELECT count(*) FROM cte1 AS cte1_c
WHERE cte1_c.name <= cte1.name AND cte1_c.id = cte1.id ORDER BY id,name
) AS c
FROM cte1
)
SELECT id,diet,group_concat(name) AS names,home FROM cte2 WHERE c <= 3 GROUP BY id;
结果是:-
通过更改最后一个 WHERE 子句中的数字,可以轻松更改多少个 names
WHERE c <= 3