Sql-Server
僅返回符合某些條件的 1 行
這是我經常遇到的一個問題,我很想知道如何解決這個問題。
我正在編寫一個足夠簡單的報告/查詢,但是在執行時,會返回具有重複值的行。我知道返回這些“重複項”的原因是因為有一列在兩行之間具有不同的數據,但是說我只想看到返回具有特定 ID 號的 1 行。選擇哪一行並不重要,只是每個 ID_NUM 只返回 1 行。
返回數據的簡化範例:
ID_NUM | PHASE | DATE | NOTE ---------------------------------- 30329 | Phase1 | 1-1-20 | example note 30329 | null | 1-1-20 | example note 21928 | Phase1 | 1-2-20 | another note 21928 | Phase1 | 4-3-19 | another note
我試過的:
- SELECT DISTINCT - 返回與簡單 SELECT 相同的結果
- SELECT DISTINCT MIN(ID_NUM) - 仍然返回重複的 ID_NUM 值,我猜是因為它們是相同的,沒有最小值。
- GROUP BY ID_NUM - 要求我在 group by 中包含每一列,並且仍然返回相同的結果。
實際範例:雖然上面是一個簡化範例,但下面顯示了我的實際查詢。case.casenum 是我只需要為每個唯一值返回 1 行的欄位/列。這是一個sybase 數據庫,它遵循mssql/t-sql 語法。
SELECT cases.casenum, cases.case_date_5, cases.class, user_tab6_data.trial_phase, user_tab6_data.maximizer_completed, user_tab6_data.maximizer_scheduled, cases.case_title, cases.open_status, cases.case_date_9, user_tab6_data.maximizer_necessary, cases.staff_1, cases.staff_8, user_tab6_data.county_of_suit, insurance.how_settled, insurance.policy_type, insurance.date_settled, user_tab6_data.value_set_date, user_tab6_data.status_note, user_tab6_data.minimum_value FROM cases, user_tab6_data, insurance WHERE (cases.casenum = user_tab6_data.case_id) AND (cases.casenum = insurance.case_num) AND (cases.class like 'A' OR cases.class like 'B' OR cases.class like 'C' OR cases.class like 'D' OR cases.class like 'E' OR cases.class like 'F' OR cases.class like 'G' OR cases.class like 'H' OR cases.class like 'I' OR user_tab6_data.trial_phase like 'Phase 1' OR cases.case_date_5 is not NULL ) AND insurance.policy_type = 'Liability' AND cases.open_status = 'O' AND cases.case_date_9 is not NULL
嘗試使用ROW_NUMBER視窗函式,如下例所示:
--demo setup drop table if exists Table1 go CREATE TABLE Table1 ( ID_NUM INTEGER, PHASE VARCHAR(6), DATE DATE, NOTE VARCHAR(12) ); --solution INSERT INTO Table1 (ID_NUM, PHASE, DATE, NOTE) VALUES ('30329', 'Phase1', '1-1-20', 'example note'), ('30329', 'null', '1-1-20', 'example note'), ('21928', 'Phase1', '1-2-20', 'another note'), ('21928', 'Phase1', '4-3-19', 'another note'); select * from ( select *,ROW_NUMBER() over(partition by ID_NUM order by ID_NUM) as rn from Table1 ) a where rn = 1
| ID_NUM | PHASE | DATE | NOTE | rn | |--------|--------|------------|--------------|----| | 21928 | Phase1 | 2020-01-02 | another note | 1 | | 30329 | Phase1 | 2020-01-01 | example note | 1 |