【问题标题】:Compare multiple values to subquery result in where clause将多个值与 where 子句中的子查询结果进行比较
【发布时间】:2020-07-08 08:04:32
【问题描述】:

我有两个相关的表如下:

用户

user_id

用户操作

user_action_id

user_id

用户操作

每当用户执行操作时,“useractions”表中都会有一个新的插入。我需要一个查询来获取那些用户只执行特定操作集的 USERACTION 行,比如(1,2)而不是(3,4)。 所以我有一个类似的查询 -

select * from USERACTIONS where (1,2) in(select user_action from USERACTIONS where user_id=100) and user_id=100; 

问题是上述查询不起作用,因为提供 (1,2) 期望子查询也返回两列,这是可以理解的。这是我得到的错误 -

错误:子查询的列太少

给一个单一的值说 (1) 或 (2) 非常有效。我想知道是否有任何方法可以使用相同的查询并将子查询的结果与多个值进行比较?我更喜欢相同的查询,因为这里演示的案例只是大型查询的一部分。

请注意,查询不应列出执行 (1,2,3,4) 的用户,应列出仅执行 (1,2) 的用户,并且 user_action 值可以是任何随机整数。

欢迎任何替代查询,但希望在同一查询中进行更改。提前致谢。

【问题讨论】:

  • 外部查询中有两个 where 子句。那是语法错误。
  • 外查询有一个where子句,内查询有一个。
  • 。 .您的查询中有三个wheres。
  • 我的错。现已编辑。感谢您指出:)

标签: mysql sql database postgresql


【解决方案1】:

试试这个:

SELECT USERS.user_id, USERACTIONS.user_action
FROM USERACTIONS
LEFT JOIN USERS ON USERS.user_id = USERACTIONS.user_id  where USERACTIONS.user_action in (1,2);

【讨论】:

  • 你可以在 where 子句中添加 ` 和 USERACTIONS.user_id=100` 来过滤这个 user_id
  • 正如我特别提到的,我希望查询返回用户仅执行 (1,2) 而不是 (1,2,3,4) 的用户操作。您的查询也会返回执行 (1,2,3,4) 的人。
  • 我不知道你的数据,但是 where 子句可能是:USERACTIONS.user_action_id in (1,2)
  • 还提到我的 user_action_id 可能是随机整数值 :)
【解决方案2】:

这适用于您的查询。

您将数字添加到 in 子句中

SELECT a.user_id
FROM
(SELECT DISTINCT user_id 
from 
 USERACTIONS 
 WHERE user_action 
               IN (1,2)) a 
INNER JOIN
(SELECT DISTINCT user_id 
from 
 USERACTIONS 
 WHERE user_action 
              NOT  IN (1,2)) b 
ON a.user_id <> b.user_id                  
; 
CREATE TABLE USERACTIONS (id INT NOT NULL AUTO_INCREMENT
                            , PRIMARY KEY(id)
                            , user_action INT
                            , user_id INT
                            
                            );
                            
                            INSERT USERACTIONS VALUES (NULL,1,100),(NULL,2,100),(NULL,3,100), (NULL,1,101),(NULL,2,101);
✓ ✓
SELECT a.user_id
FROM
(SELECT DISTINCT user_id 
from 
 USERACTIONS 
 WHERE user_action 
               IN (1,2)) a 
INNER JOIN
(SELECT DISTINCT user_id 
from 
 USERACTIONS 
 WHERE user_action 
              NOT  IN (1,2)) b 
ON a.user_id <> b.user_id
               
; 
|用户 ID | | ------: | | 101 |

db小提琴here

【讨论】:

  • 这行得通,但是在我的原始数据中,我已经有很多子查询/连接,我不想让它变得更复杂。这就是为什么我更喜欢我的查询(上面提到的)可能带有调整或可能带有较少连接/子查询的查询。我会支持你的答案,但不接受它作为最终答案。不过谢谢你的建议。 :)
  • 您可以尝试使用参数stackoverflow.com/a/5331792/5193536 的视图,但随着需求的增加,查询将稳步增长
【解决方案3】:

我看到典型的 SO 答案并没有回答 OP 的问题,而是试图将它们引向不同的方向。我知道这是旧的,但如果有人偶然发现这个,我相信这会更有帮助。

我也有一个大型企业解决方案,其中 WHERE 检查在子查询中的性能比使用 JOIN 高得多。

您可以在 WHERE 子句中设置一个变量,然后再使用它。我目前正在尝试找到一种更好的方法来执行此操作而无需设置变量,但类似这样的方法有效:

SELECT * FROM USERACTIONS
WHERE 
    ( @useraction = 
    (select user_action from USERACTIONS where user_id=100 LIMIT 1)
    = 1
    OR @useraction = 2)
AND user_id=100;

您所做的是在 WHERE 子句中创建一个变量,设置该变量,然后再使用它。这是被封装的,所以它可以匹配任何一个条件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-06
    • 2018-12-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多