【问题标题】:Django Intersection on Mysql databaseMysql 数据库上的 Django 交集
【发布时间】:2019-07-10 11:07:29
【问题描述】:

我的表有这个值:

id, product, category
1,     A,       1
2,     B,       1
3,     B,       2
4,     C,       1
5,     C,       2
6,     D,       2
7,     E,       2
8,     E,       3
9,     F,       3
10,    F,       4

我只需要在 Django 中选择匹配类别(1 或 2)和类别(3 或 4)的产品。预期结果只是产品:E

我有错误“mysql 不支持交叉点”我如何使用 Q() 来实现?

此查询不返回任何结果但有效。

main_query = Q()
main_query &= Q(category__in=[1,2])
main_query &= Q(category__in=[3,4])
models.Table.objects.filter(main_query)

【问题讨论】:

  • 你的预期输出是什么?
  • 表中的每条记录只有一个类别。该类别不可能同时在 1 或 2 中,并且在 3 或 4 中。
  • Q() 无法帮助您解决表中的单行无法同时匹配两个条件的逻辑问题。将 Q() 放入问题中有些模糊了您关于查询逻辑的原始问题。
  • 你没有理解我的问题。
  • @cuscode 你花了 40 分钟来解释你想要什么。这就是我投反对票的原因。

标签: mysql sql django


【解决方案1】:
SELECT product
FROM yourTable
GROUP BY product
HAVING COUNT(CASE WHEN category IN (1,2) THEN 1 END) > 0
   AND COUNT(CASE WHEN category IN (3,4) THEN 1 END) > 0

【讨论】:

    【解决方案2】:

    这是内联表的一种选择。

    SELECT a.* FROM 
     (SELECT * FROM tab  WHERE category IN (1,2)) AS a,
     (SELECT * FROM tab  WHERE category IN (3,4)) AS b
    WHERE a.product = b.product ;
    

    演示here

    使用 WITH 子句的另一个选项如下

    WITH cat_1_2 AS (
      SELECT * FROM tab  WHERE category IN (1,2)
    ),
    cat_3_4 AS (
      SELECT * FROM tab  WHERE category IN (3,4)
    )
    SELECT a.* FROM cat_1_2 AS a, cat_3_4 AS b
    WHERE a.product = b.product ;
    

    演示here

    【讨论】:

    • 从 86 年开始仍然使用 ANSI SQL 标准的部分内容,我在谈论逗号连接语法,它被 ... [INNER|LEFT|RIGHT] JOIN .. ON ... 语法“取代”了? thisthis 看起来不是更好吗?我希望 SQL 数据库很快就会放弃这种旧的逗号连接语法支持。我仍然会投票,因为查询的执行是正确的以获得预期的结果。
    • 感谢@Raymond Nijland 指出。我需要付出一些努力才能摆脱旧的方式。
    【解决方案3】:

    AND 条件应用于每一行,因此您没有预期的结果..但是选择与您在 IN 子句中拥有的类别相关联的行。

    你可以尝试在子查询上使用几个内连接

        SELECT t.* 
        FROM table t
        INNER JOIN (SELECT 1  cat
                    UNION
                    SELECT 2) t1 ON  t1.cat = t.category 
        INNER JOIN (SELECT 3 cat
                    UNION
                    SELECT 4) t2 ON t2.cat = t.category 
    

    【讨论】:

      【解决方案4】:

      我从@RajmondNijland 了解到INTERSECT 在 MySQL 中不存在。谢谢他。因此,您可以使用以下带有IN 运算符的查询将子查询与主查询链接:

      SELECT product 
        FROM table1 
       WHERE category IN (1,2) 
         AND product IN ( SELECT product FROM table1 WHERE category IN (3,4) );
      
      product
      -------
      E
      

      【讨论】:

      • MySQL 不支持 INTERSECT 所以你必须像你的链接说的那样模拟它。
      • 对我的情况不是一个好主意,因为我需要添加多个条件。不只是两个。我的查询需要动态和参数化。特别是我在 django 语言上需要这个
      • @cuscode 你可以解释一下你之前想要什么。
      • 问题是一样的,但我需要用 django 语言查询,跳过不支持的 mysql 交叉点的问题。我需要结果 E,因为它是唯一具有类别 1 或 2 和类别 3 或 4 的产品。事实上它有类别 2 和 3
      • @cuscode 我在您的问题的任何编辑中都看不到任何解释,告诉您i need to add multiple conditions. Not just two. My query need to dynamic and parametric.
      猜你喜欢
      • 1970-01-01
      • 2011-09-05
      • 2015-07-31
      • 2021-04-02
      • 2012-12-19
      • 1970-01-01
      • 2018-01-31
      • 2020-01-24
      • 1970-01-01
      相关资源
      最近更新 更多