【问题标题】:Complex Grouping in SQL QuerySQL 查询中的复杂分组
【发布时间】:2016-07-21 21:35:34
【问题描述】:

我需要构建一个相当复杂的 SQL 查询。原谅我,我不是 SQL 的魔法师。

这是我的两张表(大大简化了):

表A

id   request_id   page_views   step
-----------------------------------
 1   1            0            0
 2   1            0            1
 3   1            0            2
 4   1            0            3
 5   2            0            0
 6   2            0            1
 7   2            1            2
 8   3            0            0
 9   3            0            1
10   4            0            0
11   4            0            1
12   4            0            2

表B

id   name         phone       
------------------------------
1    John Deere   111-222-3333
2    Sally Sue    333-222-1111
3    Jacob Clark  434-343-4343
4    Alex Smith   222-112-2112

首先,需要在tableA.request_id = tableB.id 导致的表上进行连接:

id   request_id   page_views   step   name          phone
----------------------------------------------------------------
 1   1            0            0      John Deere   111-222-3333
 2   1            0            1      John Deere   111-222-3333
 3   1            0            2      John Deere   111-222-3333
 4   1            0            3      John Deere   111-222-3333
 5   2            0            0      Sally Sue    333-222-1111
 6   2            0            1      Sally Sue    333-222-1111
 7   2            1            2      Sally Sue    333-222-1111
 8   3            0            0      Jacob Clark  434-343-4343
 9   3            0            1      Jacob Clark  434-343-4343
10   4            0            0      Alex Smith   222-112-2112
11   4            0            1      Alex Smith   222-112-2112
12   4            0            2      Alex Smith   222-112-2112

我希望从该表中返回符合以下条件的组。通过组,我的意思是具有相同request_id 的行组。条件如下:

  1. 在组中的行中,没有一个行的 page_views 大于 0。
  2. 在组中的行中,没有一个行的 step 大于 2。

如果上述两个条件之一失败,则不会返回整个组。所以这里应该返回:

id   request_id   page_views   step   name          phone
----------------------------------------------------------------
8    3            0            0      Jacob Clark   434-343-434
9    3            0            1      Jacob Clark   434-343-434
10   4            0            0      Alex Smith    222-112-2112
11   4            0            1      Alex Smith    222-112-2112
12   4            0            2      Alex Smith    222-112-2112

“3”组(或 Jacob Clark)没有任何 page_views 大于 0 的行,并且没有任何行的 step 大于 2。与“4”组(或亚历克斯·史密斯)。

这就是问题所在。我需要一个可以处理所有这些的 SQL 查询。第一个join可以是子查询,没问题:

SELECT sub.*
FROM (
    SELECT tableA.*, tableB.name, tableB.phone
    FROM `tableA`, `tableB`
    WHERE tableA.`request_id` = tableB.id
) sub

在那之后,我就不太确定了。

任何帮助将不胜感激。

【问题讨论】:

  • join 子句可以任意复杂/简单。 join 1 完全有效,只是连接所有记录。它实际上归结为返回布尔值 true(加入正在考虑的记录)或 false(排除记录)的 join 子句。表达式是什么,完全取决于你。

标签: mysql sql join


【解决方案1】:

您需要在子查询中单独计算最大视图和步数(通过 request_id),然后使用具有足够小的最大值的 request_id:

SELECT a.*, b.name, b.phone
FROM (
   SELECT request_id
   FROM tableA
   GROUP BY request_id
   HAVING MAX(page_views) <= 0 AND MAX(step) <= 2
) AS sumQ
INNER JOIN tableA AS a ON sumQ.request_id = a.request_id
INNER JOIN tableB AS b ON a.request_id = b.id
;

或者,或者:

SELECT a.*, b.name, b.phone
FROM tableA AS a
INNER JOIN tableB AS b ON a.request_id = b.id
WHERE a.request_id IN (
     SELECT request_id
     FROM tableA
     GROUP BY request_id
     HAVING MAX(page_views) <= 0 AND MAX(step) <= 2
  )
;

根据我的经验,第一个版本通常更快。

【讨论】:

    【解决方案2】:

    您可以使用WHERE NOT EXISTS

    Select  A.id, A.request_id, A.page_views, A.step,
            B.name, B.phone
    From    TableA  A
    Join    TableB  B   On  A.request_id = B.Id
    Where   Not Exists
    (
        Select  *
        From    TableA  A2
        Where   A2.request_Id = A.request_id
        And     (A2.page_views > 0 Or A2.step > 2)
    )
    

    【讨论】:

      猜你喜欢
      • 2016-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-29
      • 2017-08-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多