如何在MySQL中使用工会合并相同的表

时间:2019-07-13 09:17:53

标签: mysql sql

我想通过结合基于不同ID的同一张表来使用联合来获取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

假设我想使用并说的话基于两个不同的id获取记录:

  

1)如果userid = 1表示应该获得10X12和14X15
2)如果userid   = 2表示它应获取17X28并与先前的userid = 1记录合并,但记录10X12和14X15不能从userid = 2中获取,因为相同   值已经存在

所以我为此联合查询编写了查询,但是对我没有帮助     预期输出:

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

4 个答案:

答案 0 :(得分:1)

NOT EXISTS的第二次查询中使用UNION

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 
)

请参见demo
结果:

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

答案 1 :(得分:1)

这是一个优先级查询。其他人已经展示了如何使用union all / not exists。当您拥有两个或三个以上的值时,这并不能一概而论:

更通用的解决方案是使用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;

您也可以在没有union 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。对于您的特定示例,order by user_id就足够了。

答案 2 :(得分:0)

您可以尝试在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

OR

代替工会 您可以尝试使用聚合的

联接
    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

答案 3 :(得分:0)

您也可以使用UNION代替GROUP BY

SELECT
  width, 
  MIN(userid) AS userid
FROM sample_values 
WHERE userid IN (1,2)
GROUP BY width

MIN(userid)将确保您优先使用最早的用户ID。与对子查询使用UNION相比,此查询还更有效


结果 View on DB Fiddle

| width | userid |
| ----- | ------ |
| 10X12 | 1      |
| 14X15 | 1      |
| 17X28 | 2      |
| 19X37 | 2      |