【问题标题】:SQL JOINING main table with two tables returning number of records - maximum of other two tables?SQL JOINING 主表与两个表返回记录数 - 其他两个表的最大值?
【发布时间】:2012-07-07 18:16:07
【问题描述】:

我有我的主表 T1,我正在从中选择许多字段:

ID
1000

我有桌子 T2:

ID      SERVICE
1000    IPTV
1000    VOIP

我有桌子 T3:

ID      DEVICE
1000    MODEM
1000    ROUTER
1000    DVC

我想将 T1 与 T2 或 T3 一起加入,它们可以但也可能根本没有值!!!! 当它们具有我希望在 SELECT 中具有来自 T2 或 T3 的最大记录数的记录数时。所以在这种情况下,T3 有 3 条记录,这是最大的,我想要 SELECT 中的 3 条记录。 (如果 T2 有 3 条记录,如果 T3 有 2 条记录,则为最大值)

但在我的 SELECT 语句中,我有 5 条我不想要的记录。正确的表达方式是什么?我下面的查询返回 5 条记录(我想要 3 条)

select t1.id,t2.service,t3.device
from t1
left outer join T2 on t1.id=t2.id
left outer join T3 on t1.id=t3.id

【问题讨论】:

  • 你确定这是你想要的吗?我觉得不合适
  • 嗯,是的。我想要结果 1000 IPTV MODEM 1000 VOIP ROUTER 1000 NULL DVC
  • 可以指定数据库和版本吗?
  • 不,没有!!!我有客户想要查看一些记录受影响的服务和设备。它们之间没有连接!所以他不想看到 5 条记录,对他来说,在我的示例中将所有信息放在 3 条记录中就足够了。现在听起来还好吗?问候
  • 您的查询将返回 6 行,而不是 5 行。

标签: sql join db2 left-join


【解决方案1】:
SELECT
    t1.id
  , t2.service
  , t3.device
FROM
        t1
    LEFT JOIN
            ( SELECT
                  ROW_NUMBER() OVER (PARTITION BY id ORDER BY service) AS rn
                , id
                , service
              FROM
                  t2
            ) AS t2
        FULL JOIN 
            ( SELECT
                  ROW_NUMBER() OVER (PARTITION BY id ORDER BY device) AS rn
                , id
                , device
              FROM
                  t3
            ) AS t3
          ON  t3.id = t2.id
          AND t3.rn = t2.rn
      ON COALESCE(t2.id, t3.id) = t1.id ;

【讨论】:

  • 这很有效,谢谢,但只是一个小问题。如果 T2 中的第一行是 VOIP 并且来自 T3 DVC,而 T2 中的第二行是选择 INTERNET 和加入后来自 T3 ROUTER,我希望得到 1000 VOIP DVC、1000 INTERNET ROUTER 的结果。但由于字母顺序,我的结果是 1000 INTERNET DVC,1000 VOIP ROUTER。这可以以某种方式改变吗? T2 和 T3 中的第一行加入结果是什么?无论如何都做得很好
  • ORDER BY serviceORDER BY device 内的ORDER BY device 更改为您想要的顺序。
  • 你说 "如果 T2 中的第一行是 VOIP 并且......" SQL 中没有表的隐式排序。表没有默认排序。看起来他们有,但他们没有。如果您在表中有主键,也许您可​​以使用它来订购。
  • 我刚刚删除了 ORDER BY 并且它有效。伙计,你是纯粹的天才!!!对于这个问题,我从两个不了解 SQL 目的的人那里得到了两个缺点,如果客户想要这样的话,你可以从中得到什么!再次感谢你,你救了我。我希望我能给你一个以上的加分!
  • 我想这种类型的查询最适合由应用程序代码处理。您可以只打两个查询,一个是FROM t1 LEFT JOIN t2,一个是FROM t1 LEFT JOIN t3,然后处理应用程序中的演示。
【解决方案2】:

这个要求听起来不对,但以下应该可以工作

SELECT T1.*, z2.ID, z2.SERVICE FROM 
(
  SELECT ID, CASE WHEN SUM(INDICATOR) >=0 THEN 1 ELSE -1 END AS INDICATOR FROM
    (
    SELECT ID, SERVICE, 1 AS INDICATOR FROM t2
    UNION ALL
    SELECT ID , DEVICE AS SERVICE , -1 AS INDICATOR FROM t3
    ) z
  GROUP BY ID
) z1
INNER JOIN
(
  SELECT ID, SERVICE, 1 AS INDICATOR FROM t2
  UNION ALL
  SELECT ID , DEVICE AS SERVICE, -1 AS INDICATOR FROM t3
) z2
ON z1.ID = z2.ID AND z1.INDICATOR = z2.INDICATOR
RIGHT JOIN T1 ON T1.ID = Z2.ID

【讨论】:

  • 您能否再次检查您的查询。我的 MAIN 表是 T1 我想从那里选择更多我没有写的字段,但是在 T1 中我有例如 STATUS、DATE、OWNER 等字段...在你的代码中我应该在哪里包含它们,因为你开始从 T2 中选择。
  • 您的代码是否包含 T2.ID 或 T3.ID 为空或两者都为空的情况? T1.ID 永远不会为空
  • 将 T1 内连接更改为右连接以处理它。
猜你喜欢
  • 2022-01-18
  • 2020-11-12
  • 2021-05-02
  • 1970-01-01
  • 1970-01-01
  • 2013-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多