惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Hugging Face - Blog
Hugging Face - Blog
WordPress大学
WordPress大学
Microsoft Azure Blog
Microsoft Azure Blog
F
Fortinet All Blogs
B
Blog RSS Feed
Last Week in AI
Last Week in AI
The Cloudflare Blog
大猫的无限游戏
大猫的无限游戏
人人都是产品经理
人人都是产品经理
P
Proofpoint News Feed
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Microsoft Security Blog
Microsoft Security Blog
博客园 - 三生石上(FineUI控件)
Y
Y Combinator Blog
GbyAI
GbyAI
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
小众软件
小众软件
雷峰网
雷峰网
C
Check Point Blog
阮一峰的网络日志
阮一峰的网络日志
博客园 - 叶小钗
博客园 - 司徒正美
U
Unit 42
量子位

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
GBase 8a QUALIFY Clause: Filtering Window Functions the S...
Michael · 2026-05-04 · via DEV Community

Michael

When you use window functions in SQL, you can't filter their results directly in a WHERE or HAVING clause — that's a well‑known limitation across many databases. GBase 8a, the China‑domestically developed MPP database from GBASE, solves this elegantly with the QUALIFY clause. Let's break down how it works, what it can do, and where you need to be careful.

Sample Table

DROP TABLE IF EXISTS emp;
CREATE TABLE emp (
    id INT,
    name VARCHAR(30) NOT NULL,
    gender VARCHAR(30) NOT NULL,
    sex INT NOT NULL,
    salary INT NOT NULL,
    dept_id INT NOT NULL
);
INSERT INTO emp VALUES(1,'Xiang Yu','Marshal',1,9000,1);
INSERT INTO emp VALUES(2,'Guan Yu','General',1,4000,2);
INSERT INTO emp VALUES(3,'Zhang Fei','Vice General',1,3000,2);
INSERT INTO emp VALUES(4,'Tang Seng','Leader',1,800,3);
INSERT INTO emp VALUES(5,'Wukong','Guard',1,700,3);
INSERT INTO emp VALUES(6,'Liu Bang','Marshal',1,6000,1);

Enter fullscreen mode Exit fullscreen mode

Why QUALIFY Exists

Suppose you want to select the employee with the lowest salary in each department. You'd typically use ROW_NUMBER() and then filter on the result. Without QUALIFY, you have to wrap the query in a subquery:

-- Traditional subquery approach
SELECT * FROM (
    SELECT id, name, dept_id, salary,
           ROW_NUMBER() OVER(PARTITION BY dept_id ORDER BY salary) rwn
    FROM emp
) sub WHERE rwn = 1;

Enter fullscreen mode Exit fullscreen mode

With QUALIFY, it's a single flat query:

SELECT id, name, dept_id, salary,
       ROW_NUMBER() OVER(PARTITION BY dept_id ORDER BY salary) rwn
FROM emp
QUALIFY ROW_NUMBER() OVER(PARTITION BY dept_id ORDER BY salary) = 1;

Enter fullscreen mode Exit fullscreen mode

Versatility of QUALIFY

1. Filtering on a Window Function

SELECT ..., ROW_NUMBER() OVER(...) rwn FROM emp QUALIFY rwn = 1;

Enter fullscreen mode Exit fullscreen mode

2. Filtering on Regular Columns or Functions

You can mix window functions and plain conditions:

SELECT ..., ROW_NUMBER() OVER(...) rwn FROM emp QUALIFY dept_id = 1;
SELECT ..., ROW_NUMBER() OVER(...) rwn FROM emp QUALIFY SUBSTR(dept_id,1,1)='1';

Enter fullscreen mode Exit fullscreen mode

3. Using Column Aliases

QUALIFY recognizes column aliases defined in the SELECT list:

SELECT id, name, dept_id AS f, ROW_NUMBER() OVER(...) rwn FROM emp QUALIFY rwn = 1;
SELECT id, name, dept_id AS f, ROW_NUMBER() OVER(...) rwn FROM emp QUALIFY f = 1;

Enter fullscreen mode Exit fullscreen mode

If you'd like WHERE and HAVING to also accept such aliases, enable:

SET _t_gcluster_support_alias_dependent = 1;

Enter fullscreen mode Exit fullscreen mode

Restrictions and Gotchas

  1. No BLOB or LONG BLOB columns in the QUALIFY condition, for either windowed or plain filters.

  2. A window function must be present somewhere in the query — either in the SELECT list or inside the QUALIFY clause itself. A plain QUALIFY without any window function is illegal:

   -- Wrong
   SELECT id, name, dept_id FROM emp QUALIFY dept_id = 1;
   -- Correct
   SELECT id, name, dept_id, ROW_NUMBER() OVER(...) rwn FROM emp QUALIFY dept_id = 1;

Enter fullscreen mode Exit fullscreen mode

  1. Strict GROUP BY alignment – When GROUP BY is present, columns in the window function's PARTITION BY / ORDER BY must match the GROUP BY columns exactly:
   -- Acceptable: window function only references dept_id
   SELECT dept_id, COUNT(*) FROM emp GROUP BY dept_id
   QUALIFY ROW_NUMBER() OVER(PARTITION BY dept_id ORDER BY id) = 1;

Enter fullscreen mode Exit fullscreen mode

  1. Cannot coexist with HAVING – A query may use either QUALIFY or HAVING, not both.

  2. WHERE comes before QUALIFY – If both are present, WHERE must appear first:

   SELECT ... FROM emp WHERE dept_id = 1 QUALIFY id = 1;

Enter fullscreen mode Exit fullscreen mode

  1. Window functions cannot be used with IN / NOT IN subqueries – The following are invalid:
   QUALIFY rwn IN (SELECT a FROM t1);           -- error
   QUALIFY ROW_NUMBER() OVER(...) IN (SELECT a FROM t1); -- error

Enter fullscreen mode Exit fullscreen mode

However, you can still use subqueries with regular columns inside QUALIFY:

   QUALIFY dept_id IN (SELECT a FROM t1);       -- OK

Enter fullscreen mode Exit fullscreen mode

  1. OR combined with IN subqueries is not allowed – Conditions like rwn=1 OR dept_id IN (...) are rejected. But AND with IN subqueries, OR with equality subqueries, or OR with static lists are fine:
   -- OK
   QUALIFY rwn=1 AND dept_id IN (SELECT ...);
   QUALIFY rwn=1 OR dept_id = (SELECT ...);
   QUALIFY rwn=1 OR dept_id IN (1,2);

Enter fullscreen mode Exit fullscreen mode

Wrap‑Up

The QUALIFY clause makes window‑function filtering natural and removes one layer of nesting from many analytical queries in your gbase database. Just keep the restrictions above in mind, and you'll write cleaner, faster SQL with GBASE's GBase 8a.