Cte

CTE 新手 - 如何在使表格獨一無二後進行計數

  • December 30, 2019

我是 CTE 的新手,通常對我的 SQL 進行子查詢。我不確定如何獲得我想要的結果,因為我一直在尋找需要子查詢的解決方案。

我在 SQL 中有下表。我正在嘗試編寫一個 CTE 來為每個人每天提供一行數據。如果一個人一天有多個位置(“位置”欄位) - 我需要排除當天的所有行。如果一個人一天有多行但位置是同一個地方 - 我只想保留一行數據。

這是原始表的範例:

原始表

這是我正在尋找的結果範例(注意 - 我不需要結果中的 ID 欄位)。

期望的結果

以下是原始數據集的定義和插入語句:

CREATE TABLE Tbl1
(`ID` int, `Person` varchar(5), `Date` varchar(10), `Where` varchar(6));

INSERT INTO Tbl1
(`ID`, `Person`, `Date`, `Where`)
VALUES
(1, 'Laura', '17/10/2019', 'School'),
(2, 'Laura', '18/10/2019', 'School'),
(3, 'Laura', '19/10/2019', 'School'),
(4, 'Laura', '19/10/2019', 'Park'),
(5, 'Laura', '20/10/2019', 'Home'),
(6, 'Laura', '21/10/2019', 'School'),
(7, 'Laura', '21/10/2019', 'School'),
(8, 'Laura', '21/10/2019', 'Home'),
(9, 'Tom', '17/10/2019', 'Home'),
(10, 'Tom', '18/10/2019', 'Home'),
(11, 'Tom', '18/10/2019', 'Home'),
(12, 'Tom', '19/10/2019', 'Home'),
(13, 'Tom', '19/10/2019', 'School'),
(14, 'Tom', '20/10/2019', 'Home');

不知道為什麼需要 CTE(或子選擇),這不是簡單的嗎

select person, date_, max(where_) from tbl1
group by person, date_
having count(distinct where_) < 2

小提琴

PS。請注意,我將表定義更改為 1) 刪除僅由 MySQL 用於引用標識符的反引號(Redshift 基於 Postgres)和 2) 重命名名稱與 SQL 關鍵字衝突的列。

我不確定這是否會複製並粘貼到 RedShift,但這就是您建構 CTE 的方式。

這個想法是按人員和日期對錶格進行排序,然後每次人員或日期更改時,排序將重置為 1。如果存在 rn > 1 的行,則意味著它有超過 1 個條目那個人和日期,因此應該被排除在外。

not exist 子句處理排除。

; WITH CTE AS
(
select ID, Person, "Date", "Where", DENSE_RANK() OVER (partition by Person, Date order by Person, Date) "rn"
from table
)
select *
from cte c1
where not exists (select 1 from cte c2 where c1.id = c2.id and c2.rn > 1)
and c1.rn = 1;

引用自:https://dba.stackexchange.com/questions/251403