有没有办法在MySQL中连接子查询时停止反复编写相同的子查询?

huangapple go评论72阅读模式
英文:

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
(&#39;aaa&#39;,&#39;dr&#39;),
(&#39;bbb&#39;,&#39;plumber&#39;),
(&#39;ccc&#39;,&#39;lab&#39;),
(&#39;ddd&#39;,&#39;dr&#39;),
(&#39;eee&#39;,&#39;plumber&#39;),
(&#39;ggg&#39;,&#39;lab&#39;),
(&#39;fff&#39;,&#39;plumber&#39;)
;


select max(case when job = &#39;dr&#39; then name else null end) dr,
		 max(case when job = &#39;plumber&#39; then name else null end) plumber,
		 max(case when job = &#39;lab&#39; then name else null end) lab
from
(
select name,job,
		if(job &lt;&gt; @p,@rn:=1,@rn:=@rn+1) rn,
		@p:=job p
 from t 
 cross join (select @rn:=0,@p:=&#39;&#39;) 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 = &#39;Doctor&#39; then name else null end as name
from occupations
order by if(occupation = &#39;Doctor&#39;,0,1), name) as t1,
(select 
    (@n2:=@n2 + 1) AS n,
    case when occupation = &#39;Professor&#39; then name else null end as name
from occupations
order by if(occupation = &#39;Professor&#39;,0,1), name) as t2,
(select 
    (@n3:=@n3 + 1) AS n,
    case when occupation = &#39;Singer&#39; then name else null end as name
from occupations
order by if(occupation = &#39;Singer&#39;,0,1), name) as t3,
(select 
    (@n4:=@n4 + 1) AS n,
    case when occupation = &#39;Actor&#39; then name else null end as name
from occupations
order by if(occupation = &#39;Actor&#39;,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);

huangapple
  • 本文由 发表于 2020年1月3日 13:11:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/59573486.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定