简体   繁体   English

来自多个表的结果MySQL

[英]Results from multiple tables MySQL

Two tables 两张桌子

Table 1 - customer table 表1-客户表

user_id      Name
1            first
2            Second

Table 2 - customer_activity table 表2-customer_activity表

user_id      type
1            downloaded_software
1            filled_download_form
2            downloaded_software
2            filled_download_form
2            purchased

Goal - To select all the customers who have downloaded_software, filled_download_form and purchased. 目标-选择所有已下载软件,已填充表单并已购买的客户。

My Query 我的查询

    SELECT SQL_CALC_FOUND_ROWS DISTINCT(c.user_id) 
      FROM customer AS c 
INNER JOIN customer_activity AS ca ON ca.user_id = c.user_id 
     WHERE ca.type IN('downloaded_software','filled_download_form','purchased') 
  ORDER BY c.user_id asc 
     LIMIT 0, 100

Result 结果

1
2

Desired Result 所需结果

2

EDIT: Comments summary: 编辑:评论摘要:

Answer for this question is below but a possible good scenario would be to exclude some items from the list. 这个问题的答案在下面,但是可能的好方案是从列表中排除一些项目。 For example, if I want to do a search for customers who have downloaded_software, filled_software_form but not purchased. 例如,如果我要搜索已下载了download_software,filled_software_form但尚未购买的客户。

This was answered by @Serpiton in this fiddle in the comments. @Serpiton在此小提琴中的评论中对此进行了回答。

You could group by user_id and count the distinct values of type . 您可以按user_id分组并计算type的不同值。 Since the WHERE restricts the values to only 3 possible, the count of distinct values should be 3 if all are found; 由于WHERE将值限制为仅3种可能,因此,如果全部找到,则不同值的计数应为3;

SELECT SQL_CALC_FOUND_ROWS c.user_id 
FROM customer AS c 
JOIN customer_activity AS ca ON ca.user_id = c.user_id 
WHERE ca.type IN('downloaded_software', 'filled_download_form', 'purchased') 
GROUP BY c.user_id
HAVING COUNT(DISTINCT ca.type) = 3
ORDER BY c.user_id 
LIMIT 0, 100

An SQLfiddle to test with . 要使用进行测试的SQLfiddle

EDIT: To answer your question from the comments, if you need to exclude a type, you can't easily use GROUP BY to find the results. 编辑:要从注释中回答您的问题,如果您需要排除类型,则不能轻易使用GROUP BY查找结果。 You can either do a self join per type (left join the excluded one and check that it results in no row); 您可以按类型进行自我联接(左联接排除的联接并检查是否没有行);

SELECT SQL_CALC_FOUND_ROWS c.user_id 
FROM customer AS c 
JOIN customer_activity AS ca1
  ON ca1.user_id = c.user_id AND ca1.type = 'downloaded_software'
JOIN customer_activity AS ca2
  ON ca2.user_id = c.user_id AND ca2.type = 'filled_download_form'
LEFT JOIN customer_activity AS ca3
  ON ca3.user_id = c.user_id AND ca3.type = 'purchased'
WHERE ca3.user_id IS NULL 
ORDER BY c.user_id 
LIMIT 0, 100

...or - not as efficient but perhaps easier if you're auto generating the query - you can do it using 3 simple subqueries using IN and NOT IN to select if the type should be included or not... ...或-效率不高,但如果您自动生成查询,则可能会更容易-您可以使用3个简单的子查询(使用INNOT IN来选择是否应包括该类型)来执行此操作...

SELECT SQL_CALC_FOUND_ROWS c.user_id 
FROM customer AS c
WHERE c.user_id IN (
  SELECT user_id FROM customer_activity WHERE type='downloaded_software'
) AND c.user_id IN (
  SELECT user_id FROM customer_activity WHERE type='filled_download_form'
) AND c.user_id NOT IN (
  SELECT user_id FROM customer_activity WHERE type='purchased'
) 
ORDER BY c.user_id
LIMIT 0,100;

An SQLfiddle showing both in action . 一个SQLfiddle展示了两者的作用

Disclaimer: in a comment in the answer of Joachim Isaksson I've suggested a variation on one of his query to the OP, who asked clarification, this is it. 免责声明:在Joachim Isaksson的回答中,我向OP提出了他的一个查询要求的变体,后者要求澄清,就是这样。

Starting from the query with the modification 从带有修改的查询开始

SELECT SQL_CALC_FOUND_ROWS c.user_id 
FROM customer AS c 
JOIN customer_activity AS ca 
  ON ca.user_id = c.user_id 
WHERE ca.type IN('downloaded_software',
                 'filled_download_form',
                 'purchased') 
GROUP BY c.user_id
HAVING COUNT(DISTINCT ca.type) = 2 AND COUNT(CASE WHEN ca.type = 'purchased' THEN 1 ELSE NULL END) = 0
ORDER BY c.user_id 
LIMIT 0, 100

the part in bold is my suggested edit. 粗体部分是我建议的编辑。

If something it's not clear outside the part I modified you should ask to Joachim Isaksson, as he is the one who wrote the query. 如果在我修改的部分之外还不清楚,您应该向Joachim Isaksson询问,因为他是编写查询的人。

My edit does what it say on the tin: the first condition check that there are only two of the three valid values of type , the second one check that 'purchased' is the one left out. 我的编辑所做的事情是这样的:第一个条件检查type的三个有效值中只有两个,第二个条件检查“购买的”是剩下的一个。 The second condition is equivalent to 第二个条件等于

SUM(CASE WHEN ca.type = 'purchased' THEN 1 ELSE 0 END) = 0

that is maybe more simple to read. 那也许更容易阅读。

The whole query is equivalent to 整个查询相当于

SELECT SQL_CALC_FOUND_ROWS c.user_id 
FROM customer AS c 
JOIN customer_activity AS ca 
  ON ca.user_id = c.user_id 
WHERE ca.type IN('downloaded_software',
                 'filled_download_form',
                 'purchased') 
GROUP BY c.user_id
HAVING COUNT(DISTINCT 
             CASE WHEN ca.type = 'downloaded_software' THEN 1 ELSE NULL END) = 1
   AND COUNT(DISTINCT 
             CASE WHEN ca.type = 'filled_download_form' THEN 1 ELSE NULL END) = 1
   AND COUNT(DISTINCT 
             CASE WHEN ca.type = 'purchased' THEN 1 ELSE NULL END) = 0
ORDER BY c.user_id 
LIMIT 0, 100

(if you only have those 3 type the WHERE is not necessary) (如果您只有这3种类型,则不需要WHERE

If you're writing the query from a programming language I will use this as the template 如果您是使用编程语言编写查询,则将其用作模板

SELECT SQL_CALC_FOUND_ROWS c.user_id 
FROM customer AS c 
JOIN customer_activity AS ca 
  ON ca.user_id = c.user_id 
WHERE ca.type IN('downloaded_software',
                 'filled_download_form',
                 'purchased') 
GROUP BY c.user_id
HAVING COUNT(DISTINCT 
             CASE WHEN ca.type = 'downloaded_software' 
                  THEN 1 ELSE NULL END) = ?downloaded?
   AND COUNT(DISTINCT 
             CASE WHEN ca.type = 'filled_download_form' 
                  THEN 1 ELSE NULL END) = ?filled?
   AND COUNT(DISTINCT 
             CASE WHEN ca.type = 'purchased' 
                  THEN 1 ELSE NULL END) = ?purchased?
ORDER BY c.user_id 
LIMIT 0, 100

with ?downloaded? ?downloaded? , ?filled? ?filled? and ?purchased? ?purchased? as parameters. 作为参数。 1 mean that the type need to be present, 0 mean that the parameter need to be missing 1表示需要显示类型,0表示需要缺失参数

To answer the other question For example, only target customers who have neither filled_download_form nor purchased. 回答另一个问题例如,仅针对既没有fill_download_form也没有购买的客户。 What would be the query for that? 这将是什么查询? just fill the parameters accordingly. 只需相应地填写参数即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM