选择存在的数据[关闭]

问题描述 投票:0回答:3

我有

LEFT JOIN
ed 的三张桌子。在这种情况下,我需要使用
COALESCE(ID, ID1)
用 ID1 替换丢失的 ID。

目标是仅获取 ID 及其所有相关数据条目,给定 OPS 列中的值“w”。

我尝试使用

EXISTS
子句,但它只返回列 OPS 的值为 'w' 的行,而不返回与同一 ID 相关的其他行:

SELECT t1.id, t1.age, t2.operation, t3.ops
FROM table1 AS t1
LEFT JOIN table2 AS t2 ON COALESCE(t2.id, t2.id1) = t1.id 
LEFT JOIN table3 AS t3 ON COALESCE(t3.id, t3.id1) = t1.id
WHERE EXISTS (SELECT 1 
              FROM table3 
              WHERE id = t1.id
                AND (t3.ops = 'w'))

现在我试着弄清楚为什么我的

EXISTS
子句不能正常工作。

资料:
db<>小提琴

这是我想用代码产生的结果:

id 年龄 操作 操作
1 23 A q
1 23 A w
1 23 A e
1 23 q
1 23 w
1 23 e
1 23 C q
1 23 C w
1 23 C e
2 25 A q
2 25 A w
2 25 q
2 25 w
4 43 A q
4 43 A w
4 43 q
4 43 w
sql sql-server subquery left-join window-functions
3个回答
2
投票

如果我理解正确的话,我会推荐窗口函数而不是

exist
来检查每个组是否有操作
w

SELECT *
FROM (
    SELECT t1.id AS t1id, 
        t1.age AS t1age, 
        t2.id AS t2id, 
        t2.id1 AS t2id1, 
        t2.operation AS t2operation, 
        t3.id AS t3id, 
        t3.id1 AS t3id1, 
        t3.ops AS t3ops,
        MAX(CASE WHEN t3.ops = 'w' then 1 else 0 end) OVER(PARTITION BY t1.id) has_ops_w
    FROM table1 AS t1
    LEFT JOIN table2 AS t2 ON COALESCE(t2.id, t2.id1) = t1.id 
    LEFT JOIN table3 AS t3 ON COALESCE(t3.id, t3.id1) = t1.id
) t
WHERE has_ops_w = 1

你的 DB Fiddle:

t1id t1age t2id t2id1 t2操作 t3id t3id1 t3ops has_ops_w
1 23 1 1 A 1 1 q 1
1 23 1 1 A 1 w 1
1 23 1 1 A 1 e 1
1 23 1 1 1 q 1
1 23 1 1 w 1
1 23 1 1 e 1
1 23 1 C 1 1 q 1
1 23 1 C 1 w 1
1 23 1 C 1 e 1
2 25 2 2 A 2 2 q 1
2 25 2 2 A 2 w 1
2 25 2 2 2 2 q 1
2 25 2 2 2 w 1
4 43 4 4 A 4 4 q 1
4 43 4 4 A 4 w 1
4 43 4 4 4 q 1
4 43 4 4 w 1

1
投票

GMB 指定的窗口函数可以工作,但是,我认为使用 EXISTS 子句有些混乱。

SELECT t1.id, t1.age, t2.operation, t3.ops
FROM table1 AS t1
LEFT JOIN table2 AS t2
ON COALESCE(t2.id, t2.id1) = t1.id 
LEFT JOIN table3 AS t3 ON COALESCE(t3.id, t3.id1) = t1.id
WHERE EXISTS (
  SELECT 1 
  FROM table3 inner_t3
  WHERE COALESCE(inner_t3.id, inner_t3.id1) = t1.id -- your join above wasn't 
                                                    -- on ID alone. This one 
                                                    -- shouldn't be either
  AND inner_t3.ops = 'w'  -- Make sure you have proper reference to inner 
                          -- table using alias.
)

0
投票

行得通。那么是不是因为从 ID1 替换 ID 的 CLAUSE 需要在 exists 子句中再次重复?

SELECT t1.id, t1.age, t2.operation, t3.ops
FROM table1 AS t1
LEFT JOIN table2 AS t2 ON t2.id = t1.id OR (t2.id IS NULL AND t2.id1 = t1.id)
LEFT JOIN table3 AS t3 ON t3.id = t1.id OR (t3.id IS NULL AND t3.id1 = t1.id)
WHERE EXISTS (
  SELECT 1 
  FROM table2 AS t2 
  LEFT JOIN table3 AS t3 ON t3.id = t1.id OR (t3.id IS NULL AND t3.id1 = t1.id)
  WHERE t1.id = t1.id
  AND (t3.ops = 'w')
);
© www.soinside.com 2019 - 2024. All rights reserved.