合并来自相同 table 的 2 select 个查询
Joining 2 select queries from the same table
我有 两个 SQL 查询 来自同一个 table 如下。
Query1 -> select * from (select (start_date::text), (end_date::text), count("NEW") "NEW" from table_name where refnum in (select refnum from table_name where start_date in (SELECT start_date FROM table_name ORDER BY ID DESC LIMIT 1)) and "NEW">0 group by start_date, end_date order by end_date DESC limit 10) top_10 order by end_date ASC
Query2 -> select * from (select (start_date::text), (end_date::text), count("DELETED") "DELETED" from table_name where refnum in (select refnum from table_name where start_date in (SELECT start_date FROM table_name ORDER BY ID DESC LIMIT 1)) and "DELETED">0 group by start_date, end_date order by end_date DESC limit 10) top_10 order by end_date ASC
请建议一个最终查询以合并这两个子查询,从而产生一个 table
我想要最终的 table 包含列 start_date、end_date、NEW、DELETED
您可以使用 FULL JOIN
,如:
select
coalesce(a.start_date, b.start_date) as start_date,
coalesce(a.end_date, b.end_date) as end_date,
a.new,
b.deleted
from (
-- query #1 here; exclude the ORDER BY clause
) a
full join (
-- query #2 here; exclude the ORDER BY clause
) b on b.start_date = a.start_date and b.end_date = a.end_date
order by coalesce(a.end_date, b.end_date) ASC
您可以使用 union
运算符来堆叠表格:
select * from (select (start_date::text), (end_date::text), count("NEW") "NEW" from table_name where refnum in (select refnum from table_name where start_date in (SELECT start_date FROM table_name ORDER BY ID DESC LIMIT 1)) and "NEW">0 group by start_date, end_date order by end_date DESC limit 10) top_10 order by end_date ASC
UNION
select * from (select (start_date::text), (end_date::text), count("DELETED") "DELETED" from table_name where refnum in (select refnum from table_name where start_date in (SELECT start_date FROM table_name ORDER BY ID DESC LIMIT 1)) and "DELETED">0 group by start_date, end_date order by end_date DESC limit 10) top_10 order by end_date ASC
您 可以 使用 FULL [OUTER] JOIN
就像建议的那样。 但是 请注意,行与 NULL
值不匹配!如果您的结果行之一在 start_date
或 end_date
中包含 NULL
,则不会合并“匹配”行。有变通办法,但我不打算这样做,因为我不希望它适用。此外,您的查询已经在 order by end_date DESC
中断,它首先对 NULL
值进行排序 - 可能是无意的 ...
无论哪种方式,如果您选择FULL JOIN
,请使用USING
子句:
SELECT start_date, end_date, a.new, b.deleted
FROM ( <"top_10" subquery of Query1 here> ) a
FULL JOIN ( <"top_10" subquery of Query2 here> ) b USING (start_date, end_date) -- !
ORDER BY end_date;
A clause of the form USING ( a, b, ... )
is shorthand for ON left_table.a = right_table.a AND left_table.b = right_table.b ....
Also, USING
implies that only one of each pair of equivalent columns
will be included in the join output, not both.
COALESCE(a.start_date, b.start_date)
等的需求消失了。更短、更简单、更快。
你 可能 甚至 NATURAL
加入:
SELECT start_date, end_date, a.new, b.deleted
FROM a
NATURAL FULL JOIN b -- !
ORDER BY end_date;
NATURAL
is shorthand for a USING
list that mentions all columns in the
two tables that have matching names. If there are no common column
names, NATURAL
is equivalent to ON TRUE
.
只有当您的子查询严格符合描述时才有意义,并且不会改变。我只看到极少数情况下这是可取的。
不过,这一切很可能是给猪涂口红。通常,您应该能够将两个查询合并为一个 - 简化(并修复)您当前拥有的内容。
向我们展示确切的 table 定义和确切的职位描述,我很可能可以用更好的查询来代替这句话。
我有 两个 SQL 查询 来自同一个 table 如下。
Query1 -> select * from (select (start_date::text), (end_date::text), count("NEW") "NEW" from table_name where refnum in (select refnum from table_name where start_date in (SELECT start_date FROM table_name ORDER BY ID DESC LIMIT 1)) and "NEW">0 group by start_date, end_date order by end_date DESC limit 10) top_10 order by end_date ASC
Query2 -> select * from (select (start_date::text), (end_date::text), count("DELETED") "DELETED" from table_name where refnum in (select refnum from table_name where start_date in (SELECT start_date FROM table_name ORDER BY ID DESC LIMIT 1)) and "DELETED">0 group by start_date, end_date order by end_date DESC limit 10) top_10 order by end_date ASC
请建议一个最终查询以合并这两个子查询,从而产生一个 table
我想要最终的 table 包含列 start_date、end_date、NEW、DELETED
您可以使用 FULL JOIN
,如:
select
coalesce(a.start_date, b.start_date) as start_date,
coalesce(a.end_date, b.end_date) as end_date,
a.new,
b.deleted
from (
-- query #1 here; exclude the ORDER BY clause
) a
full join (
-- query #2 here; exclude the ORDER BY clause
) b on b.start_date = a.start_date and b.end_date = a.end_date
order by coalesce(a.end_date, b.end_date) ASC
您可以使用 union
运算符来堆叠表格:
select * from (select (start_date::text), (end_date::text), count("NEW") "NEW" from table_name where refnum in (select refnum from table_name where start_date in (SELECT start_date FROM table_name ORDER BY ID DESC LIMIT 1)) and "NEW">0 group by start_date, end_date order by end_date DESC limit 10) top_10 order by end_date ASC
UNION
select * from (select (start_date::text), (end_date::text), count("DELETED") "DELETED" from table_name where refnum in (select refnum from table_name where start_date in (SELECT start_date FROM table_name ORDER BY ID DESC LIMIT 1)) and "DELETED">0 group by start_date, end_date order by end_date DESC limit 10) top_10 order by end_date ASC
您 可以 使用 FULL [OUTER] JOIN
就像建议的那样。 但是 请注意,行与 NULL
值不匹配!如果您的结果行之一在 start_date
或 end_date
中包含 NULL
,则不会合并“匹配”行。有变通办法,但我不打算这样做,因为我不希望它适用。此外,您的查询已经在 order by end_date DESC
中断,它首先对 NULL
值进行排序 - 可能是无意的 ...
无论哪种方式,如果您选择FULL JOIN
,请使用USING
子句:
SELECT start_date, end_date, a.new, b.deleted
FROM ( <"top_10" subquery of Query1 here> ) a
FULL JOIN ( <"top_10" subquery of Query2 here> ) b USING (start_date, end_date) -- !
ORDER BY end_date;
A clause of the form
USING ( a, b, ... )
is shorthand forON left_table.a = right_table.a AND left_table.b = right_table.b ....
Also,USING
implies that only one of each pair of equivalent columns will be included in the join output, not both.
COALESCE(a.start_date, b.start_date)
等的需求消失了。更短、更简单、更快。
你 可能 甚至 NATURAL
加入:
SELECT start_date, end_date, a.new, b.deleted
FROM a
NATURAL FULL JOIN b -- !
ORDER BY end_date;
NATURAL
is shorthand for aUSING
list that mentions all columns in the two tables that have matching names. If there are no common column names,NATURAL
is equivalent toON TRUE
.
只有当您的子查询严格符合描述时才有意义,并且不会改变。我只看到极少数情况下这是可取的。
不过,这一切很可能是给猪涂口红。通常,您应该能够将两个查询合并为一个 - 简化(并修复)您当前拥有的内容。
向我们展示确切的 table 定义和确切的职位描述,我很可能可以用更好的查询来代替这句话。