英文:
Is there a way to stop writing same subqueries again and again when joining subqueries in MySQL
问题
我需要对这些子查询执行完全外连接。
SET @n1 = 0;
SET @n2 = 0;
SELECT * FROM
(SELECT (@n1:=@n1 + 1) AS n, name FROM occupations WHERE occupation="Doctor") AS t1
LEFT OUTER JOIN
(SELECT (@n2:=@n2 + 1) AS n, name FROM occupations WHERE occupation="Professor") AS t2
ON t1.n=t2.n
UNION
SELECT * FROM
(SELECT (@n1:=@n1 + 1) AS n, name FROM occupations WHERE occupation="Doctor") AS t1
RIGHT OUTER JOIN
(SELECT (@n2:=@n2 + 1) AS n, name FROM occupations WHERE occupation="Professor") AS t2
ON t1.n=t2.n;
在这里,我不得不一次又一次地写相同的子查询。
如果有以下类似的方法,将会非常容易:
SET @n1 = 0;
SET @n2 = 0;
t1 = (SELECT (@n1:=@n1 + 1) AS n, name FROM occupations WHERE occupation="Doctor");
t2 = (SELECT (@n2:=@n2 + 1) AS n, name FROM occupations WHERE occupation="Professor");
SELECT * FROM t1 LEFT OUTER JOIN t2 ON t1.n=t2.n
UNION
SELECT * FROM t1 RIGHT OUTER JOIN AS t2 ON t1.n=t2.n;
但我不知道有任何方法可以这样做。同时,我也不想创建任何视图或临时表来执行此操作。请帮助。谢谢。
英文:
I need to full outer join these subqueries
SET @n1 = 0;
SET @n2 = 0;
SELECT * FROM
(SELECT (@n1:=@n1 + 1) AS n, name FROM occupations WHERE occupation="Doctor") AS t1
LEFT OUTER JOIN
(SELECT (@n2:=@n2 + 1) AS n, name FROM occupations WHERE occupation="Professor") AS t2
ON t1.n=t2.n
UNION
SELECT * FROM
(SELECT (@n1:=@n1 + 1) AS n, name FROM occupations WHERE occupation="Doctor") AS t1
RIGHT OUTER JOIN
(SELECT (@n2:=@n2 + 1) AS n, name FROM occupations WHERE occupation="Professor") AS t2
ON t1.n=t2.n
;
Here I had to write the same subqueries again and again.
If there is any method like below it will be very easy
SET @n1 = 0;
SET @n2 = 0;
t1 = (SELECT (@n1:=@n1 + 1) AS n, name FROM occupations WHERE occupation="Doctor");
t2 = (SELECT (@n2:=@n2 + 1) AS n, name FROM occupations WHERE occupation="Professor");
SELECT * FROM t1 LEFT OUTER JOIN t2 ON t1.n=t2.n
UNION
SELECT * FROM t1 RIGHT OUTER JOIN AS t2 ON t1.n=t2.n;
But I don't know any method to do something like that. Also I don't want to create any views or temporary tables to do this. Please help. Thank you.
答案1
得分: 1
透过 MySQL 中的条件聚合通常可以解决枢轴问题,例如:
drop table if exists t;
create table t
(name varchar(10), job varchar(10));
insert into t values
('aaa','dr'),
('bbb','plumber'),
('ccc','lab'),
('ddd','dr'),
('eee','plumber'),
('ggg','lab'),
('fff','plumber')
;
select max(case when job = 'dr' then name else null end) dr,
max(case when job = 'plumber' then name else null end) plumber,
max(case when job = 'lab' then name else null end) lab
from
(
select name,job,
if(job <> @p,@rn:=1,@rn:=@rn+1) rn,
@p:=job p
from t
cross join (select @rn:=0,@p:='') r
order by job, name
) s
group by rn;
+------+---------+------+
| dr | plumber | lab |
+------+---------+------+
| aaa | bbb | ccc |
| ddd | eee | ggg |
| NULL | fff | NULL |
+------+---------+------+
3 rows in set (0.02 sec)
请注意,这里生成了一个行号以启用分组(在版本 8.0 中,您可以使用 row_number
函数),并按名称进行排序。
英文:
Pivot questions are usually tackled using conditional aggregation in mysql for example
drop table if exists t;
create table t
(name varchar(10), job varchar(10));
insert into t values
('aaa','dr'),
('bbb','plumber'),
('ccc','lab'),
('ddd','dr'),
('eee','plumber'),
('ggg','lab'),
('fff','plumber')
;
select max(case when job = 'dr' then name else null end) dr,
max(case when job = 'plumber' then name else null end) plumber,
max(case when job = 'lab' then name else null end) lab
from
(
select name,job,
if(job <> @p,@rn:=1,@rn:=@rn+1) rn,
@p:=job p
from t
cross join (select @rn:=0,@p:='') r
order by job, name
) s
group by rn;
+------+---------+------+
| dr | plumber | lab |
+------+---------+------+
| aaa | bbb | ccc |
| ddd | eee | ggg |
| NULL | fff | NULL |
+------+---------+------+
3 rows in set (0.02 sec)
Note the generation of a row number to enable the group (in version 8.0 you could use row_number function) and the ordering by name.
答案2
得分: 0
我能做我想做的事情。这是我的代码。谢谢大家。
SET @n1 = 0;
SET @n2 = 0;
SET @n3 = 0;
SET @n4 = 0;
select t1.name, t2.name, t3.name, t4.name from
(select
(@n1:=@n1 + 1) AS n,
case when occupation = '医生' then name else null end as name
from occupations
order by if(occupation = '医生',0,1), name) as t1,
(select
(@n2:=@n2 + 1) AS n,
case when occupation = '教授' then name else null end as name
from occupations
order by if(occupation = '教授',0,1), name) as t2,
(select
(@n3:=@n3 + 1) AS n,
case when occupation = '歌手' then name else null end as name
from occupations
order by if(occupation = '歌手',0,1), name) as t3,
(select
(@n4:=@n4 + 1) AS n,
case when occupation = '演员' then name else null end as name
from occupations
order by if(occupation = '演员',0,1), name) as t4
where t1.n=t2.n and t2.n=t3.n and t3.n=t4.n and not(t1.name is null and t2.name is null and t3.name is null and t4.name is null);
英文:
I were able to do what i wanted to do. Here is my code. Thank you everyone.
SET @n1 = 0;
SET @n2 = 0;
SET @n3 = 0;
SET @n4 = 0;
select t1.name, t2.name, t3.name, t4.name from
(select
(@n1:=@n1 + 1) AS n,
case when occupation = 'Doctor' then name else null end as name
from occupations
order by if(occupation = 'Doctor',0,1), name) as t1,
(select
(@n2:=@n2 + 1) AS n,
case when occupation = 'Professor' then name else null end as name
from occupations
order by if(occupation = 'Professor',0,1), name) as t2,
(select
(@n3:=@n3 + 1) AS n,
case when occupation = 'Singer' then name else null end as name
from occupations
order by if(occupation = 'Singer',0,1), name) as t3,
(select
(@n4:=@n4 + 1) AS n,
case when occupation = 'Actor' then name else null end as name
from occupations
order by if(occupation = 'Actor',0,1), name) as t4
where t1.n=t2.n and t2.n=t3.n and t3.n=t4.n and not(t1.name is null and t2.name is null and t3.name is null and t4.name is null);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论