如何创建表的视图,其中包含表记录的子集,所有表的列,以及附加的“flag”列,如果表包含特定类型的记录,则其值设置为“X”?例如,请考虑以下关系表Relations
,其中类型的值代表H'-human, 'D'-dog
:
id | type | relation | related
--------------------------------
H1 | H | knows | D2
H1 | H | owns | D2
H2 | H | knows | D1
H2 | H | owns | D1
H3 | H | knows | D1
H3 | H | knows | D2
H3 | H | treats | D1
H3 | H | treats | D2
D1 | D | bites | H3
D2 | D | bites | H3
此表中可能没有任何特定的记录顺序。
我寻求创建一个视图Humans
,其中包含来自knows
和所有Relations
列的所有人与狗的Relations
关系以及其他列如果某个关系中的某个人拥有某人,则isOwner
存储'X'
:
id | type | relation | related | isOwner
------------------------------------------
H1 | H | knows | D2 | X
H2 | H | knows | D1 | X
H3 | H | knows | D1 |
但与此挣扎了很多。你知道一种方法吗,最好是在一次CREATE VIEW
电话中,还是以任何方式?
答案 0 :(得分:3)
CREATE VIEW vHumanDogRelations
AS
SELECT
id,
type,
relation,
related,
-- Consider using a bit 0/1 instead
CASE
WHEN EXISTS (
SELECT 1
FROM Relations
WHERE
id = r.id
AND related = r.related -- Owns someone or this related only?
AND relation = 'owns'
) THEN 'X'
ELSE ''
END AS isOwner
FROM Relations r
WHERE
relation = 'knows'
AND type = 'H'
AND related = 'D';
答案 1 :(得分:2)
您应该能够将以下select
放入视图定义
select *, case when exists
(select * from Relations where id = r.id and relation= 'owns') then 'X'
else '' end as isOwner
from Relations r
答案 2 :(得分:1)
您还可以使用PIVOT来获得所需的结果。我会详细解释这个方法,因为最终的查询可能会让人感到困惑。
首先,从Relation
派生一个子集,其中type
为H
和relation
knows
或owns
,替换{{1} } owns
的值:
X
根据你的例子,你会得到这个:
SELECT
id,
type,
relation = CASE relation WHEN 'owns' THEN 'X' ELSE relation END,
related
FROM Relations
WHERE type = 'H'
AND relation IN ('knows', 'owns')
接下来,将此PIVOT子句应用于第一个查询的结果:
id type relation related
-- ---- -------- -------
H1 H knows D2
H1 H owns D2
H2 H knows D1
H2 H owns D1
H3 H knows D1
H3 H knows D2
它会将具有相同PIVOT (
MAX(relation) FOR relation IN (knows, X)
) AS p
值的行分组到一行,并将id, type, related
拆分为两列,relation
和knows
:
X
此时,您只需要为主SELECT子句中的输出稍微重新排列列集,将id type related knows X
-- ---- ------- ----- ----
H1 H D2 knows X
H2 H D1 knows X
H3 H D1 knows NULL
H3 H D2 knows NULL
重命名为knows
并将relation
重命名为X
沿着方式:
isOwner
输出:
SELECT
id,
type,
relation = knows,
related,
isOwner = X
...
当然,如果有必要,可以很容易地用空字符串替换NULL。
最后一步可能是将此额外过滤器添加到主查询中:
id type relation related isOwner
-- ---- -------- ------- -------
H1 H knows D2 X
H2 H knows D1 X
H3 H knows D1 NULL
H3 H knows D2 NULL
以防有人在没有实际知道的情况下拥有狗(并且你不想在输出中使用它们)。
因此,完整的查询将如下所示:
WHERE knows IS NOT NULL
此解决方案的SQL小提琴演示可用here。