【问题标题】:selective filter of join of three tables三表连接的选择性过滤器
【发布时间】:2012-12-26 18:41:24
【问题描述】:

我有三个表 Table1、Table2 和 Table3。

Table1 与 Table2 具有一对多的关系。 Table2 与 Table3 是一对多的关系。

说table1有

-------------
t1key
-------------
a
b

Table2 has 
-------------
t1key | t2key
--------------
a        c
a        d
b        x
b        y


Table 3
------------
t2key | t3key
-------------
c      e
c      f
c      g
d      h
d      i
d      j
x      m
x      n
x      o
y      p
y      q
y      r

我想要加入三个表,以便它只返回 table3 中 t2key 的第一个唯一匹配

join的结果应该是

a c  e
a d  h
b x  m
b y  p

目前我的应用程序对所有三个表进行连接,返回所有可能的行。我需要用上述条件过滤掉它。

SELECT * FROM Table1 AS T1  
LEFT OUTER JOIN Table2 T2 ON T1.t1Key = T2.t1Key 
LEFT OUTER JOIN Table2 T3 ON T2.t2Key = T3.t2Key

【问题讨论】:

  • 请注意格式化。更好的是,编写一个模式(CREATE TABLE 和一些INSERT TABLE 语句)或在SQLfiddle 上提供一个表示例。如果我们无法正确查看数据,就很难回答 SQL 问题。
  • 请告诉我们哪个 RDBMS?

标签: sql


【解决方案1】:

像这样:

SELECT 
  t2.t1Key, 
  t2.t2key, 
  MIN(t3.t3key) t3key
FROM Table1 AS T1  
INNER JOIN Table2 T2 ON T1.t1Key = T2.t1Key 
INNER JOIN Table3 T3 ON T2.t2Key = T3.t2Key
GROUP BY t2.t1Key, 
         t2.t2key;

SQL Fiddle Demo

这会给你:

| T1KEY | T2KEY | T3KEY |
-------------------------
|     a |     c |     e |
|     a |     d |     h |
|     b |     x |     m |
|     b |     y |     p |

【讨论】:

    【解决方案2】:

    您需要使用GROUP BY 子句并首先使用MIN()

    SELECT t2.t1key, t2.t2key, MIN(t3.t3key) AS t3key
    FROM Table1 AS T1  
    LEFT JOIN Table2 T2 ON T1.t1Key = T2.t1Key 
    LEFT JOIN Table3 T3 ON T2.t2Key = T3.t2Key
    GROUP BY t2.t1Key, t2.t2key;
    

    See this SQLFiddle

    如果您只想显示每个表中可用的数据,请使用INNER JOIN 而不是LEFT JOIN
    例如假设Table2'b', 'q'中有一行。
    然后如果你使用LEFT JOIN,它会显示这样的结果

    | T1KEY | T2KEY |  T3KEY |
    --------------------------
    |     a |     c |      e |
    |     a |     d |      h |
    |     b |     q | (null) | <-- It will show null value too
    |     b |     x |      m |
    |     b |     y |      p |
    

    Demo

    使用INNER JOIN 不会显示该记录

    Demo

    【讨论】:

      【解决方案3】:
      DECLARE @table1 table
      (
          t1 char(1)
      )
      INSERT INTO @table1
      SELECT 'a' UNION ALL
      SELECT 'b' 
      
      
      DECLARE @table2 table
      (
          t1 char(1),
          t2 char(1)
      )
      INSERT INTO @table2
      SELECT 'a', 'c' UNION ALL
      SELECT 'a', 'd' UNION ALL
      SELECT 'b', 'x' UNION ALL
      SELECT 'b', 'y' 
      
      DECLARE @table3 table
      (
          t1 char(1),
          t2 char(1)
      )
      INSERT INTO @table3
      SELECT 'c', 'e' UNION ALL
      SELECT 'c', 'f' UNION ALL
      SELECT 'c', 'g' UNION ALL
      
      SELECT 'd', 'h' UNION ALL
      SELECT 'd', 'i' UNION ALL
      SELECT 'd', 'j' UNION ALL
      
      SELECT 'x', 'm' UNION ALL
      SELECT 'x', 'n' UNION ALL
      SELECT 'x', 'o' UNION ALL
      
      SELECT 'y', 'p' UNION ALL
      SELECT 'y', 'q' UNION ALL
      SELECT 'y', 'r' 
      
      
      
      SELECT 
      
          t1.t1,
          t2.t2,
          min(t3.t2)
      FROM @table2 t2
      INNER JOIN @table3 t3
      ON t3.t1 = t2.t2
      INNER JOIN @table1 t1
      ON t1.t1 = t2.t1
      GROUP BY t1.t1,
          t2.t2
      

      【讨论】:

      • @user1971858 你检查过我的逻辑吗
      【解决方案4】:
      SELECT t1.t1key,t2.t2key,t3.t3key 
      FROM Table1 t1  
      INNER JOIN Table2 t2 ON t1.t1Key = t2.t1Key 
      LEFT OUTER JOIN Table2 t3 ON t2.t2Key = t3.t2Key
      group by t2.t1key,t2.t2key;
      

      【讨论】:

        猜你喜欢
        • 2018-08-30
        • 2021-12-19
        • 1970-01-01
        • 2015-08-26
        • 2016-12-07
        • 2020-10-09
        • 2016-05-19
        • 2013-07-10
        • 2019-02-07
        相关资源
        最近更新 更多