如何在mysql中使用union合并同一个表

如何在mysql中使用union合并同一个表,mysql,sql,Mysql,Sql,我想通过基于不同id组合相同的表,使用union来获取mysql记录 Table name :sample_value id width userid 1 10X12 1 2 14X15 1 3 17X28 2 4 10X12 2 5 14X15 2 6 19X37 2 Mysql联合查询: select * from table sample_values where userid=1 union distinct sel

我想通过基于不同id组合相同的表,使用union来获取mysql记录

Table name :sample_value

id   width  userid
1    10X12   1
2    14X15   1
3    17X28   2
4    10X12   2
5    14X15   2
6    19X37   2
Mysql联合查询:

select * from table sample_values where userid=1 
union distinct
select * from table sample_values where userid=2
假设我想使用union获取基于两个不同id的记录,比如:

1) 如果userid=1,则表示如果userid =2意味着它应该得到17X28并与userid=1的上一条记录相结合,但记录10X12和14X15不是从userid=2得到的,因为它们是相同的 价值已经存在

所以我为这个联合查询写了一个查询,但它对我没有帮助 预期产出:

id   width  userid
1    10X12   1
2    14X15   1
3    17X28   2
6    19X37   2

您可以尝试使用userid=1和userid=1与userid=2之间不匹配的值之间的联合

    select * 
    from table sample_values 
    where userid=1 
    union (
    select b.* 
    from table sample_values a
    left JOIN sample_values b on a.width = b.with 
        and a.userid = 1 and b.userid=2
    where b.width is null
    ) t

而不是工会 您可以尝试使用带有agregated的连接

    select s.* from sample_values s
    inner join (
        select width, min(userid) min_width
        from sample_values 
        group by width
    ) t on t.min_width= s.width and t.userid = s.userid

联合的第二次查询中使用
不存在

select * from sample_values where userid=1 
union all
select * from sample_values s
where s.userid = 2 and not exists (
  select 1 from sample_values
  where userid = 1 and width = s.width 
)
请参阅。
结果:


您也可以利用
分组方式来代替
联合

SELECT
  width, 
  MIN(userid) AS userid
FROM sample_values 
WHERE userid IN (1,2)
GROUP BY width
MIN(userid)
将确保您优先选择最早的userid。此查询也比对子查询使用
UNION
更有效


结果


这是一个优先级查询。其他人已经展示了如何为此使用
联合所有
/
不存在。当您有两个或三个以上的值时,这不能很好地概括:

更通用的解决方案是使用MySQL 8+中的窗口函数:

select sv.*
from (select sv.*,
             row_number() over (partition by width
                                order by (case when user_id = 1 then 1 else 2 end)
                               ) as seqnum
      from sample_value sv
     ) sv
where seqnum = 1;
您也可以在不使用
联合all
的情况下执行此操作:

select sv.*
from sample_value sv
where sv.user_id = (select sv2.user_id
                    from sample_value sv2
                    where sv2.width = sv.width
                    order by (case when sv2.user_id = 1 then 1 else 2 end)
                    limit 1
                   );

在所有这些示例中,我使用了
case
作为
order by
。对于您的特定示例,
按用户id排序
就足够了。

此查询不起作用,而且看起来很复杂,您能简化一下吗?您有错误吗??显示错误消息。。错误的结果??显示actula结果出错如果我添加了新记录但没有重复值,则此查询不起作用请检查它是否起作用请解释为什么使用,请为userid=2选择所需的min(id)仅1行,具有最小id的行。实际期望的输出是结果集应获得具有唯一记录的值意味着如果用户1具有相同的值,用户2也具有相同的值,则组合唯一值集应获得。这并不意味着id 2只有1条记录。谢谢您做了这么多完美的工作,我只想知道where子句之后选择1是什么?是否仅获取1条记录或userid=1选择1可以是select*或选择0或选择null。没关系。它是EXISTS的占位符。所以,如果返回了任何内容,那么EXISTS就是trye。@forpas您能解释一下查询中的notexists部分代码的作用是:只有在没有userid=1且宽度相同的行时,它才会返回userid=2的行。
select sv.*
from (select sv.*,
             row_number() over (partition by width
                                order by (case when user_id = 1 then 1 else 2 end)
                               ) as seqnum
      from sample_value sv
     ) sv
where seqnum = 1;
select sv.*
from sample_value sv
where sv.user_id = (select sv2.user_id
                    from sample_value sv2
                    where sv2.width = sv.width
                    order by (case when sv2.user_id = 1 then 1 else 2 end)
                    limit 1
                   );