【问题标题】:Complicated MYSQL query selecting from two tables从两个表中选择复杂的 MYSQL 查询
【发布时间】:2018-02-20 20:22:36
【问题描述】:

我需要做一个 MYSQL 查询从“table_in”中选择用户,它的格式与 table_1 相同

 table_1
 id  Field_id  user_id  value
 1      9        1     "hello"
 2      10       1     "Multi"
 3      9        2     "Something"
 4      10       2     "Single"

 table_2
 id  user_id  status        specs
 1      1     "Busy"       "this is a test"
 2      2     "Idle"       "this is another test"
 3      2     "Busy"       "another test again"
 4      1     "Relaxing"   "something else"

我需要从 table_in 中选择用户,其中满足以下任一条件

  1. table_1 field_id=10 包含“Multi”
  2. table_2 状态不忙

然后将结果保存在新表table_out中

所以到目前为止我得到的是这个

  CREATE TEMPORARY TABLE table_out
    SELECT * FROM table_1 WHERE user_id in (SELECT user_id from table_in) 
    AND (field_id=10 AND value='Multi')
    OR (SELECT * from table_2 where status!='Busy')

我不是 SQL 专家,我上面的 MY-SQL 语句不起作用。我认为最后一个 OR 语句可能是错误的,它试图从状态不忙的 table_2 中进行选择。

所以基本上进入 table_out 的用户必须全部来自“table_in”并且要么有(字段 10 设置为多),要么是 table_2 中的同一用户(状态!=忙碌)

有人知道怎么做吗?

更新: 找到了我自己的解决方案。使用 table_in,通过仅选择那些不是“多”的值来创建第二个表,然后从查询 table_2 中将那些不忙的 user_id 放入另一个表中,然后从 table_in 中删除这些值。

还是谢谢

【问题讨论】:

  • 那么,这里真的有3张桌子吗? table_intable_1table_2?
  • 是的,table_in 包含实际用户,然后从这些用户中查看 table_1 和 table_2,查看 table_in 中的用户对应的信息是否包含字段 10=multi 或同一用户具有 table_2 状态不忙。所以你只能使用 table_in 中的 user_ids
  • 因此,如果 table_in 中的用户在 table_2 中有任何“忙碌”的条目,则您无法选择它们。因此,table_in 中的用户必须在 field_id=10 中具有“multi”,或者在 table_2 中的状态为“not busy”

标签: mysql


【解决方案1】:

您可以尝试使用联合声明。 我这里没有任何 mysql 数据库来测试它,但它应该看起来像这样

-- since table_in is a temporary table, we need to copy it first.
CREATE TEMPORARY TABLE table_in2 SELECT * FROM table_in;

CREATE TEMPORARY TABLE table_out SELECT table_out_alias.*
                             FROM (
                                    SELECT
                                      user_id AS user_id,
                                      value   AS value,
                                      ''      AS specs
                                    FROM table_1
                                    WHERE user_id IN (SELECT user_id
                                                      FROM table_in)
                                          AND (field_id = 10 AND value = 'Multi')
                                    UNION ALL
                                    SELECT
                                      user_id AS user_id,
                                      ''      AS value,
                                      specs   AS specs
                                    FROM table_2
                                    WHERE status != 'Busy' AND user_id IN (SELECT user_id
                                                                           FROM table_in2)
                                  ) AS table_out_alias

如果我没看错你的问题:)

【讨论】:

  • 只是想知道为什么在 value 之后的第二行和 user_id 之后的最后一行有单引号?谢谢!
  • 它给出了一个错误:不能在最后一行重新打开table_in
  • 对每个Select 语句使用Inner JOINtable_in 而不是子查询。这可能会解决您的错误。
  • 由于我还不知道如何加入,能否请您发布整个代码
  • 您只使用临时表吗?我的查询中的引号用于创建相同的结果,请参阅 tdjprog 的回复。 UNION 中的每个 SELECT 语句必须具有相同数量的列
【解决方案2】:

从我所看到的......也许这样的事情会起作用......当然,我是 SQL Server,但我认为这适用于 MySQL。

Select t1.*
From Table_in TIN
JOIN Table_1 T1 ON TIN.User_ID = T1.User_ID
JOIN Table_2 T2 ON TIN.User_ID = T2.User_ID
Where (T1.Field_ID = 10 AND T1.Value = 'Multi')
OR (T2.Status != 'Busy')

【讨论】:

  • SELECT t1.* 有什么作用??
  • 只选择来自Table_1别名T1的列
  • 好的,非常感谢,检查需要很长时间,因为我必须将其上传到服务器,然后将其与 SQL 过程中的其他代码集成
  • T1 是否有两次别名?在第一行,然后在第三行?我是 sql 新手,不好意思问
  • 现在的问题是它只选择了table_2中的用户。如果用户不在表 2 中,则不会被选中。如果用户不在 table_2 中,他们应该被选中
【解决方案3】:

您必须使用 UNION ALL 运算符。

UNION 运算符用于组合两个或多个 SELECT 语句的结果集。

  • UNION 中的每个 SELECT 语句必须具有相同数量的 列
  • 列也必须具有相似的数据类型

  • 每个 SELECT 语句中的列的顺序也必须相同。

    CREATE TEMPORARY TABLE table_out
    SELECT * FROM table_1 WHERE user_id in (SELECT user_id from table_in) AND (field_id=10 AND value='Multi')
    

默认情况下,UNION 运算符仅选择不同的值。允许 重复值,使用 UNION ALL

UNION ALL
    SELECT t2.id, t_in.field_id, t2.user_id, t_in.value
    FROM table_2 AS t2
    INNER JOIN table_in AS t_in
    ON t2.user_id = t_in.user_id
    WHERE t2.status != 'Busy';

【讨论】:

  • 我结合了你的顶级代码和第二个代码,然后得到了那个错误
  • 只尝试没有联合运算符的第二部分。有什么错误吗?
【解决方案4】:

我想你会发现这符合你的要求:

SELECT *
  FROM table_in ti
  INNER JOIN table_1 t1
    ON t1.user_id = ti.user_id
  LEFT OUTER JOIN table_2 t2
    ON t2.USER_ID = ti.USER_ID
  WHERE (t1.field_id = 10 AND t1.value = 'Multi') OR
        t2.status <> 'Busy'

要按预期进行这项工作,table_2 应该是外部(可选)连接。实际上,由于我对这个问题没有完全掌握,很可能 table_1 和 table_2 都应该是外连接。好吧,你可以玩得更远。

我必须做出一些假设,我将其封装在this SQLFiddle 中。请注意,在小提琴中,我只使用 1 的user_id 填充了table_in,只是为了测试它。根据需要更改它以进一步测试。

祝你好运。

编辑

小提琴的代码是:

create table table_in(user_id int);

insert into table_in(user_id) values (1);



create table table_1(id int, field_id int, user_id int, value varchar(20));

 insert into table_1 (id,  Field_id,  user_id,  value) values (1,      9 ,       1,     'hello');
 insert into table_1 (id,  Field_id,  user_id,  value) values (2,      10,       1,     'Multi');
 insert into table_1 (id,  Field_id,  user_id,  value) values (3,      9 ,       2,     'Something');
 insert into table_1 (id,  Field_id,  user_id,  value) values (4,      10,       2,     'Single');

 create table table_2 (id int, user_id int, status varchar(10), specs varchar(25));

insert into table_2(id,  user_id,  status, specs) value (1,      1,     'Busy'     ,  'this is a test');
insert into table_2(id,  user_id,  status, specs) value ( 2,      2,     'Idle'     ,  'this is another test');
insert into table_2(id,  user_id,  status, specs) value ( 3,      2,     'Busy'     ,  'another test again');
insert into table_2(id,  user_id,  status, specs) value ( 4,      1,     'Relaxing' ,  'something else');

把它放在这里是因为 SQLFiddle 今天似乎像乒乓球一样在线和离线。 :-(

【讨论】:

  • 感谢您的帮助,它给出了错误:重复的列名 ID
  • 好吧,也许这就是你可以做的事情。祝你好运。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-03-16
  • 2013-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-16
  • 1970-01-01
相关资源
最近更新 更多