【问题标题】:Problems with joining tables sql连接表sql的问题
【发布时间】:2013-10-09 15:40:42
【问题描述】:

我无法为这种情况创建适当的 sql 查询。我有 1 个存储 CATEGORY_ID 的表。

p_xref
+-------------+
| CATEGORY_ID |
+-------------+
|        5005 |
+-------------+

此 CATEGORY_ID 是父类别,它可能有子类别 ID。我在下一张桌子上检查了这一点。对于此表中的每个 CATEGORY_ID,都有一个 PARENT_CAT_ID。如果该类别没有父级,则将其设置为 -1。我的查询当前在第一个表中查找 PARENT_CAT_ID 和 CATEGORY_ID 之间的匹配项。

category_profile
+-------------+---------------+
| CATEGORY_ID | PARENT_CAT_ID |
+-------------+---------------+
|        5028 |          5005 |
|        5005 |            -1 |
+-------------+---------------+

然后我将此类别 ID 与决赛桌进行匹配,以获取 ITEM_ID。

item_xref
+-------------+---------+
| CATEGORY_ID | ITEM_ID |
+-------------+---------+
|        5028 |    6767 |
+-------------+---------+

我当前查询的问题是它只抓取子类别,不适用于父类别。我可以做相反的事情并匹配所有父类别而不匹配子类别。有没有办法把这两个查询结合起来?

查询 1:仅抓取子类别匹配项

SELECT DISTINCT DATE FROM promotion p 
                LEFT JOIN p_xref pcx ON p.P_ID = pcx.P_ID
                LEFT JOIN category_profile cp ON pcx.CATEGORY_ID = cp.PARENT_CAT_ID   
                LEFT JOIN item_xref icx ON cp.CATEGORY_ID = icx.CATEGORY_ID
                WHERE icx.ITEM_ID = "randomID"

查询 2:仅抓取父类别匹配项

                SELECT DISTINCT DATE FROM promotion p 
                LEFT JOIN p_xref pcx ON p.P_ID = pcx.P_ID 
                LEFT JOIN item_xref icx ON pcx.CATEGORY_ID = icx.CATEGORY_ID
                WHERE icx.ITEM_ID = "RandomID"

谢谢!

【问题讨论】:

  • 可能需要使用 NOT IN 子句
  • 您考虑过使用 UNION ALL 吗?
  • 也许我理解错了,但是如果您将 WHERE 更改为指向 cp.parent_cat_id="randomID" (查询父猫而不是猫),您的第一个查询不会起作用吗?此外,如果没有该猫的子记录(根据最终连接),则将省略父猫记录。只是几个想法 - 也许我误解了这个问题......
  • 如果不详细查看@它,您可以使用 1/2 查询的视图,然后将视图重新加入第二条语句...这将简化它(也许您正在运行根据您使用的 SQL 版本进行外部连接限制,这可以解决这个问题...)
  • where 子句正在寻找与 CATEGORY_ID 匹配的 ITEM_ID。第一个查询的问题是所有父类别 ID 都不匹配。我会看看其他建议,看看它们是否有帮助!

标签: mysql sql


【解决方案1】:

改变这个:

LEFT JOIN category_profile cp ON pcx.CATEGORY_ID = cp.PARENT_CAT_ID   

到这里

JOIN category_profile cp ON pcx.CATEGORY_ID = cp.PARENT_CAT_ID   
or pcx.category_id = cp.category_id

【讨论】:

  • 在没有明确的 LEFT/RIGHT 的情况下降级为普通的“JOIN”不是一个好主意
  • 为什么会这样?
  • 因为它可能会混淆许多:1 或 1:1 的所需关系。明确的 INNER 和 LEFT 总是明智的。将 LEFT 从 OP 过度简化为 INNER 可能会省略必要的行。
  • 我没有意识到您可以在 JOIN 语句中使用 OR 条件!不过,我将我的加入保留为 LEFT JOIN。
【解决方案2】:

我会从相反的方向开始以获取要查找的项目,然后以另一种方式链接。通过使用 WHERE 子句,您可以强制进入 INNER 连接与 LEFT 连接。 (没有生产表列的列表,但假设日期来自该表)

select distinct 
      p.Date
   from
      item_xref ixc
         JOIN category_profile cp
            on icx.category_id = cp.category_id
            LEFT JOIN p_xref x1
               on cp.category_id = x1.category_id
               OR cp.parent_cat_id = x1.category_id
               left join promotion p
                  on x1.category_id = p.p_id
   where
      icx.item_id = "randomid"

确保一个 Item_id 上 item_xref 表的索引 category_id 上的 category_profile 索引

【讨论】:

    猜你喜欢
    • 2017-07-08
    • 1970-01-01
    • 1970-01-01
    • 2011-10-25
    • 1970-01-01
    • 2014-03-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多