Mysql 从子祖父母关系中的不同表中获取名称
我有三张桌子:Mysql 从子祖父母关系中的不同表中获取名称,mysql,parent-child,Mysql,Parent Child,我有三张桌子: CREATE TABLE category (id integer, parent_id integer); CREATE TABLE category_name (id integer, name (varchar(20), language_id); CREATE TABLE language (language_id integer, language_name); 我可以通过以下声明获得儿童-父母-祖父母关系: SELECT c.id, c.parent_id, p.p
CREATE TABLE category (id integer, parent_id integer);
CREATE TABLE category_name (id integer, name (varchar(20), language_id);
CREATE TABLE language (language_id integer, language_name);
我可以通过以下声明获得儿童-父母-祖父母关系:
SELECT c.id, c.parent_id, p.parent_id
FROM category AS p, category AS c
WHERE p.id = c.parent_id AND p.parent_id IS NOT NULL;
但是我还需要从表category_name中获取孩子、父母和祖父母的名字,其中language_id=3
如果没有子女-父母-祖父母关系,则获取姓名的查询如下:
SELECT c.id, n.name
FROM category c
LEFT JOIN category_name n ON c.id = n.id AND language_ID = 3
但是如何将这两个语句合并成一个语句,这样我就可以得到三个name列?
也就是说,每一行都应该有自己、其父代和祖辈(如果后者存在)的ID和名称
如何进行此组合查询
以下是表格和一些示例数据:
CREATE TABLE category (id integer, parent_id integer);
INSERT INTO category VALUES (1,null);
INSERT INTO category VALUES (2,null);
INSERT INTO category VALUES (3,1);
INSERT INTO category VALUES (4,2);
INSERT INTO category VALUES (5,2);
INSERT INTO category VALUES (6,4);
INSERT INTO category VALUES (7,2);
INSERT INTO category VALUES (8,7);
INSERT INTO category VALUES (9,7);
INSERT INTO category VALUES (10,7);
INSERT INTO category VALUES (11,3);
CREATE TABLE category_name (id integer, name varchar(20), language_id integer);
INSERT INTO category_name VALUES (1, 'CDs', 3);
INSERT INTO category_name VALUES (2, 'Books', 3);
INSERT INTO category_name VALUES (3, 'Music', 3);
INSERT INTO category_name VALUES (4, 'Novels', 3);
INSERT INTO category_name VALUES (5, 'Childrens books', 3);
INSERT INTO category_name VALUES (6, 'European', 3);
INSERT INTO category_name VALUES (7, 'Science', 3);
INSERT INTO category_name VALUES (8, 'Math', 3);
INSERT INTO category_name VALUES (9, 'Informatics', 3);
INSERT INTO category_name VALUES (10, 'Physics', 3);
INSERT INTO category_name VALUES (11, 'Classic', 3);
INSERT INTO category_name VALUES (1, 'CDs', 4);
INSERT INTO category_name VALUES (2, 'Livres', 4);
INSERT INTO category_name VALUES (3, 'Musique', 4);
INSERT INTO category_name VALUES (4, 'Romans', 4);
CREATE TABLE language (language_id integer, language_name varchar(15));
INSERT INTO language (3, 'English');
INSERT INTO language (4, 'French');
以下是我希望获得一些样本的方式(对于c.id=5和8):
我尝试了以下代码,但它给出了 错误代码:1054。“on子句”中的未知列“p.parent\u id”
SELECT c.id, c.parent_id, p.parent_id, nc.name, np.name, ng.name
FROM category1 AS p, category1 AS c
LEFT JOIN category_name1 AS nc ON c.id = nc.id AND nc.language_id = 3
LEFT JOIN category_name1 AS np ON c.parent_id = np.id AND np.language_id = 3
LEFT JOIN category_name1 AS ng ON p.parent_id = ng.id AND ng.language_id = 3 AND p.parent_id IS NOT NULL
WHERE p.id = c.parent_id AND p.parent_id IS NOT NULL;
我不难说出孩子和父母的名字,但祖父母的名字似乎不在我的掌握范围之内:(
下面是代码工作
SELECT x.id, x.pid, x.gpid,
nc.name childName, np.name parentName, ng.name gpName
FROM
(SELECT c.id , c.parent_id AS pid, p.parent_id AS gpid
FROM
category AS c
LEFT JOIN category AS p ON p.id = c.parent_id
) x
LEFT JOIN category_name AS nc ON x.id = nc.id AND nc.language_id = 3
LEFT JOIN category_name AS np ON x.pid = np.id AND np.language_id = 3
LEFT JOIN category_name AS ng ON x.gpid = ng.id AND ng.language_id = 3;
请尝试并发表评论。查询和结果都基于我自己的示例
语言名称
,类别名称
和语言id=
某物,按父id进行分组
查询:
select l.language_name, cl.name, c.parent_id
from category c
left join
category_name cl
on c.parent_id = cl.id
inner join
language l
on cl.language_id = l.language_id
where l.language_id = 30
group by c.parent_id
;
select l.language_name, cl.name, c.parent_id
from language l
left join
category_name cl
on cl.language_id = l.language_id
left join
category c
on c.parent_id = cl.id
group by l.language_id
;
select x.id, x.pid, x.gpid,
cl.name ccat, cl2.name pcat, cl3.name gpcat
from
(SELECT c.id , c.parent_id as pid,
p.parent_id gpid
FROM category AS c
left join category AS p
on p.id = c.parent_id
WHERE c.id in (5, 8)
) x
left join
category_name cl
on cl.id = x.id
left join category_name cl2
on cl2.id = x.pid
left join category_name cl3
on cl3.id = x.gpid
group by x.id
;
结果:
LANGUAGE_NAME NAME PARENT_ID
eng cat4c 4
LANGUAGE_NAME NAME PARENT_ID
jpn cat1 (null)
kor cat3 3
eng cat4 4
ID PID GPID CCAT PCAT GPCAT
5 2 (null) Children Books (null)
8 7 2 Math Science Books
以下查询正在为每种语言
选择类别名称
和父id
查询:
select l.language_name, cl.name, c.parent_id
from category c
left join
category_name cl
on c.parent_id = cl.id
inner join
language l
on cl.language_id = l.language_id
where l.language_id = 30
group by c.parent_id
;
select l.language_name, cl.name, c.parent_id
from language l
left join
category_name cl
on cl.language_id = l.language_id
left join
category c
on c.parent_id = cl.id
group by l.language_id
;
select x.id, x.pid, x.gpid,
cl.name ccat, cl2.name pcat, cl3.name gpcat
from
(SELECT c.id , c.parent_id as pid,
p.parent_id gpid
FROM category AS c
left join category AS p
on p.id = c.parent_id
WHERE c.id in (5, 8)
) x
left join
category_name cl
on cl.id = x.id
left join category_name cl2
on cl2.id = x.pid
left join category_name cl3
on cl3.id = x.gpid
group by x.id
;
结果:
LANGUAGE_NAME NAME PARENT_ID
eng cat4c 4
LANGUAGE_NAME NAME PARENT_ID
jpn cat1 (null)
kor cat3 3
eng cat4 4
ID PID GPID CCAT PCAT GPCAT
5 2 (null) Children Books (null)
8 7 2 Math Science Books
根据OP的更新问题编辑样本数据和预期结果
查询:
select l.language_name, cl.name, c.parent_id
from category c
left join
category_name cl
on c.parent_id = cl.id
inner join
language l
on cl.language_id = l.language_id
where l.language_id = 30
group by c.parent_id
;
select l.language_name, cl.name, c.parent_id
from language l
left join
category_name cl
on cl.language_id = l.language_id
left join
category c
on c.parent_id = cl.id
group by l.language_id
;
select x.id, x.pid, x.gpid,
cl.name ccat, cl2.name pcat, cl3.name gpcat
from
(SELECT c.id , c.parent_id as pid,
p.parent_id gpid
FROM category AS c
left join category AS p
on p.id = c.parent_id
WHERE c.id in (5, 8)
) x
left join
category_name cl
on cl.id = x.id
left join category_name cl2
on cl2.id = x.pid
left join category_name cl3
on cl3.id = x.gpid
group by x.id
;
结果:
LANGUAGE_NAME NAME PARENT_ID
eng cat4c 4
LANGUAGE_NAME NAME PARENT_ID
jpn cat1 (null)
kor cat3 3
eng cat4 4
ID PID GPID CCAT PCAT GPCAT
5 2 (null) Children Books (null)
8 7 2 Math Science Books
请尝试并发表评论。查询和结果都基于我自己的示例
此查询选择语言名称
,类别名称
和语言id=
某物,按父id进行分组
查询:
select l.language_name, cl.name, c.parent_id
from category c
left join
category_name cl
on c.parent_id = cl.id
inner join
language l
on cl.language_id = l.language_id
where l.language_id = 30
group by c.parent_id
;
select l.language_name, cl.name, c.parent_id
from language l
left join
category_name cl
on cl.language_id = l.language_id
left join
category c
on c.parent_id = cl.id
group by l.language_id
;
select x.id, x.pid, x.gpid,
cl.name ccat, cl2.name pcat, cl3.name gpcat
from
(SELECT c.id , c.parent_id as pid,
p.parent_id gpid
FROM category AS c
left join category AS p
on p.id = c.parent_id
WHERE c.id in (5, 8)
) x
left join
category_name cl
on cl.id = x.id
left join category_name cl2
on cl2.id = x.pid
left join category_name cl3
on cl3.id = x.gpid
group by x.id
;
结果:
LANGUAGE_NAME NAME PARENT_ID
eng cat4c 4
LANGUAGE_NAME NAME PARENT_ID
jpn cat1 (null)
kor cat3 3
eng cat4 4
ID PID GPID CCAT PCAT GPCAT
5 2 (null) Children Books (null)
8 7 2 Math Science Books
以下查询正在为每种语言
选择类别名称
和父id
查询:
select l.language_name, cl.name, c.parent_id
from category c
left join
category_name cl
on c.parent_id = cl.id
inner join
language l
on cl.language_id = l.language_id
where l.language_id = 30
group by c.parent_id
;
select l.language_name, cl.name, c.parent_id
from language l
left join
category_name cl
on cl.language_id = l.language_id
left join
category c
on c.parent_id = cl.id
group by l.language_id
;
select x.id, x.pid, x.gpid,
cl.name ccat, cl2.name pcat, cl3.name gpcat
from
(SELECT c.id , c.parent_id as pid,
p.parent_id gpid
FROM category AS c
left join category AS p
on p.id = c.parent_id
WHERE c.id in (5, 8)
) x
left join
category_name cl
on cl.id = x.id
left join category_name cl2
on cl2.id = x.pid
left join category_name cl3
on cl3.id = x.gpid
group by x.id
;
结果:
LANGUAGE_NAME NAME PARENT_ID
eng cat4c 4
LANGUAGE_NAME NAME PARENT_ID
jpn cat1 (null)
kor cat3 3
eng cat4 4
ID PID GPID CCAT PCAT GPCAT
5 2 (null) Children Books (null)
8 7 2 Math Science Books
根据OP的更新问题编辑样本数据和预期结果
查询:
select l.language_name, cl.name, c.parent_id
from category c
left join
category_name cl
on c.parent_id = cl.id
inner join
language l
on cl.language_id = l.language_id
where l.language_id = 30
group by c.parent_id
;
select l.language_name, cl.name, c.parent_id
from language l
left join
category_name cl
on cl.language_id = l.language_id
left join
category c
on c.parent_id = cl.id
group by l.language_id
;
select x.id, x.pid, x.gpid,
cl.name ccat, cl2.name pcat, cl3.name gpcat
from
(SELECT c.id , c.parent_id as pid,
p.parent_id gpid
FROM category AS c
left join category AS p
on p.id = c.parent_id
WHERE c.id in (5, 8)
) x
left join
category_name cl
on cl.id = x.id
left join category_name cl2
on cl2.id = x.pid
left join category_name cl3
on cl3.id = x.gpid
group by x.id
;
结果:
LANGUAGE_NAME NAME PARENT_ID
eng cat4c 4
LANGUAGE_NAME NAME PARENT_ID
jpn cat1 (null)
kor cat3 3
eng cat4 4
ID PID GPID CCAT PCAT GPCAT
5 2 (null) Children Books (null)
8 7 2 Math Science Books
像这样的方法应该会奏效:
SELECT
c.id AS childId, cname.name AS childName,
p.id AS parentId, pname.name AS parentName,
g.id AS grandparentId, gname.name AS grandparentName
FROM category p
INNER JOIN category c ON (p.id = c.parent_id)
LEFT JOIN category g ON (p.parent_id = g.id)
LEFT JOIN category_name cname ON (c.id = cname.id AND cname.language_ID = 3)
LEFT JOIN category_name pname ON (p.id = pname.id AND pname.language_ID = 3)
LEFT JOIN category_name gname ON (g.id = gname.id AND gname.language_ID = 3)
WHERE p.parent_id IS NOT NULL;
我觉得应该有一个更整洁的方法来做到这一点,但目前还看不到。类似的方法应该可以:
SELECT
c.id AS childId, cname.name AS childName,
p.id AS parentId, pname.name AS parentName,
g.id AS grandparentId, gname.name AS grandparentName
FROM category p
INNER JOIN category c ON (p.id = c.parent_id)
LEFT JOIN category g ON (p.parent_id = g.id)
LEFT JOIN category_name cname ON (c.id = cname.id AND cname.language_ID = 3)
LEFT JOIN category_name pname ON (p.id = pname.id AND pname.language_ID = 3)
LEFT JOIN category_name gname ON (g.id = gname.id AND gname.language_ID = 3)
WHERE p.parent_id IS NOT NULL;
我觉得应该有一个更简洁的方法来做这件事,但目前还看不到。你能给我们展示一些样本数据和基于样本数据的预期结果吗?:)你能给我们展示一些基于样本数据的样本数据和预期结果吗?:)但是我如何能同时将其与儿童-父母-祖父母查询相结合?很抱歉,您能用一些示例数据更新您的问题到您的表中,并向我们显示基于此的预期结果吗?@user1956527我已根据您的问题更新更新了我的答案,请尝试并发表评论。如果您还需要语言名称
,那么请查看更新的SQLFIDLE演示:)@user1956527另一个答案似乎并不限制数据。不管怎样,只要对你有用。。。另外,您在问题的第一位也没有提到基于此查询创建视图
!但是我如何能同时将其与儿童-父母-祖父母查询相结合?很抱歉,您能用一些示例数据更新您的问题到您的表中,并向我们显示基于此的预期结果吗?@user1956527我已根据您的问题更新更新了我的答案,请尝试并发表评论。如果您还需要语言名称
,那么请查看更新的SQLFIDLE演示:)@user1956527另一个答案似乎并不限制数据。不管怎样,只要对你有用。。。另外,您在问题的第一位也没有提到基于此查询创建视图
!因为某种原因没有看到这个。这个也很好用。并且可以基于它创建一个视图,这显然与第一个带有子查询的视图不兼容。但是我没有得到第一类,也就是说,祖父母没有被列为孩子。出于某种原因,我没有看到这一类。这一类也非常有效。并且可以基于它创建一个视图,这显然与第一个带有子查询的视图不兼容。但是我没有得到第一类,也就是说,祖父母没有被列为孩子。