答案 0 :(得分:0)
您通常会在某种报告工具中执行“群组标题”。但是,如果您愿意,它可以在纯SQL中完成。
您从“标准加入”中的数据开始:
-- The basic query
SELECT
table_1.table_1_id, phone, name, some_data,
row_number() over(partition by table_1.table_1_id order by some_data)
FROM
table_1
JOIN table_2 ON table_2.table_1_id = table_1.table_1_id ;
这将产生下表:
table_1_id | phone | name | some_data | row_number ---------: | :---- | :--- | :-------- | ---------: 1 | 502 | aa | a | 1 1 | 502 | aa | b | 2 1 | 502 | aa | j | 3 1 | 502 | aa | n | 4 2 | 268 | bb | a | 1 2 | 268 | bb | s | 2 2 | 268 | bb | y | 3 5 | 984 | ee | a | 1 5 | 984 | ee | n | 2 5 | 984 | ee | w | 3
如果你想添加一些标题行,并且不显示 phone, name, we need to *add* these data to the query. This is done by making a second specific
SELECT for the headers, and
UNION ALL`的值,第一个。
也就是说,我们将使用:
-- This query produces the 'headers'
SELECT DISTINCT
table_1.table_1_id,
phone,
name,
'' AS some_data,
true as is_header -- this marks this row as a 'header'
FROM
table_1
JOIN table_2 ON table_2.table_1_id = table_1.table_1_id
UNION ALL
-- This query produces the actual data
SELECT
table_1.table_1_id,
phone,
name,
some_data,
false as is_header
FROM
table_1
JOIN table_2 ON table_2.table_1_id = table_1.table_1_id ;
现在,我们将其作为 sub 查询,并制作一些额外的逻辑来决定需要显示哪些数据,以及需要隐藏哪些数据(实际上,显示为''):< / p>
-- A few tricks to do the formatting
SELECT
-- Here we decide which information to show, which not
case when is_header then cast(table_1_id as text) else '' end AS table_1_id,
case when is_header then phone else '' end AS phone,
case when is_header then name else '' end as name,
case when is_header then '' else some_data end as some_data
FROM
(-- This query produces the 'headers'
SELECT DISTINCT
table_1.table_1_id,
phone,
name,
'' AS some_data,
true as is_header -- this marks this row as a 'header
FROM
table_1
JOIN table_2 ON table_2.table_1_id = table_1.table_1_id
UNION ALL
-- This query produces the actual data
SELECT
table_1.table_1_id,
phone,
name,
some_data,
false as is_header
FROM
table_1
JOIN table_2 ON table_2.table_1_id = table_1.table_1_id
) AS q
ORDER BY
q.table_1_id, is_header DESC /* Header goes first */, some_data ;
这会产生:
table_1_id | phone | name | some_data :--------- | :---- | :--- | :-------- 1 | 502 | aa | | | | a | | | b | | | j | | | n 2 | 268 | bb | | | | a | | | s | | | y 5 | 984 | ee | | | | a | | | n | | | w
您可以在 dbfiddle here
中查看整个设置和模拟数据请注意,不会保留您指定的订单。你应该有一些关于如何订购的逻辑。 SQL没有“插入顺序”或“自然顺序”的概念;你总是要选择你想要的那个(否则,数据库将选择最方便的那个,并且可能从一次执行变为下一次执行)
答案 1 :(得分:0)
有一个很好的功能,如the documentation for FFmpeg here。
使用它可以为单个查询/结果集获取不同分组条件的几个集合。感谢您提供的数据grouping sets
让我们从最简单的查询开始:
SELECT
table_1.table_1_id, phone, name, some_data
FROM
table_1 JOIN table_2 ON table_2.table_1_id = table_1.table_1_id;
┌────────────┬───────┬──────┬───────────┐ │ table_1_id │ phone │ name │ some_data │ ╞════════════╪═══════╪══════╪═══════════╡ │ 1 │ 502 │ aa │ a │ │ 1 │ 502 │ aa │ b │ │ 1 │ 502 │ aa │ n │ │ 1 │ 502 │ aa │ j │ │ 5 │ 984 │ ee │ w │ │ 5 │ 984 │ ee │ a │ │ 5 │ 984 │ ee │ n │ │ 2 │ 268 │ bb │ s │ │ 2 │ 268 │ bb │ a │ │ 2 │ 268 │ bb │ y │ └────────────┴───────┴──────┴───────────┘
这里需要按前三列添加组:
SELECT
table_1.table_1_id, phone, name--, some_data
FROM
table_1 JOIN table_2 ON table_2.table_1_id = table_1.table_1_id
GROUP BY GROUPING SETS ((table_1.table_1_id, phone, name));
┌────────────┬───────┬──────┐ │ table_1_id │ phone │ name │ ╞════════════╪═══════╪══════╡ │ 2 │ 268 │ bb │ │ 5 │ 984 │ ee │ │ 1 │ 502 │ aa │ └────────────┴───────┴──────┘
注意双括号。实际上它等于简单GROUP BY table_1.table_1_id, phone, name
(因为我注释了some_data
列,它不在组中)。但我们想在查询中添加更多数据:
SELECT
table_1.table_1_id, phone, name, some_data
FROM
table_1 JOIN table_2 ON table_2.table_1_id = table_1.table_1_id
GROUP By GROUPING SETS ((table_1.table_1_id, phone, name),(table_1.table_1_id, phone, name, some_data));
┌────────────┬───────┬──────┬───────────┐ │ table_1_id │ phone │ name │ some_data │ ╞════════════╪═══════╪══════╪═══════════╡ │ 1 │ 502 │ aa │ a │ │ 1 │ 502 │ aa │ b │ │ 1 │ 502 │ aa │ j │ │ 1 │ 502 │ aa │ n │ │ 1 │ 502 │ aa │ ░░░░ │ │ 2 │ 268 │ bb │ a │ │ 2 │ 268 │ bb │ s │ │ 2 │ 268 │ bb │ y │ │ 2 │ 268 │ bb │ ░░░░ │ │ 5 │ 984 │ ee │ a │ │ 5 │ 984 │ ee │ n │ │ 5 │ 984 │ ee │ w │ │ 5 │ 984 │ ee │ ░░░░ │ └────────────┴───────┴──────┴───────────┘
这几乎是我们想要的。我们只需要以适当的方式订购数据并清理一些列:
SELECT
case when some_data is null then table_1.table_1_id end as table_1_id,
case when some_data is null then phone end as phone,
case when some_data is null then name end as name,
some_data
FROM
table_1
JOIN table_2 ON table_2.table_1_id = table_1.table_1_id
group by grouping sets((table_1.table_1_id, phone, name), (table_1.table_1_id, phone, name, some_data))
order by table_1.table_1_id, some_data nulls first;
┌────────────┬───────┬──────┬───────────┐ │ table_1_id │ phone │ name │ some_data │ ╞════════════╪═══════╪══════╪═══════════╡ │ 1 │ 502 │ aa │ ░░░░ │ │ ░░░░ │ ░░░░ │ ░░░░ │ a │ │ ░░░░ │ ░░░░ │ ░░░░ │ b │ │ ░░░░ │ ░░░░ │ ░░░░ │ j │ │ ░░░░ │ ░░░░ │ ░░░░ │ n │ │ 2 │ 268 │ bb │ ░░░░ │ │ ░░░░ │ ░░░░ │ ░░░░ │ a │ │ ░░░░ │ ░░░░ │ ░░░░ │ s │ │ ░░░░ │ ░░░░ │ ░░░░ │ y │ │ 5 │ 984 │ ee │ ░░░░ │ │ ░░░░ │ ░░░░ │ ░░░░ │ a │ │ ░░░░ │ ░░░░ │ ░░░░ │ n │ │ ░░░░ │ ░░░░ │ ░░░░ │ w │ └────────────┴───────┴──────┴───────────┘
宾果!希望这是你要求的。