الانتقال إلى المحتوى الرئيسي
تُرجع جملة EXCEPT فقط الصفوف الناتجة عن الاستعلام الأول دون الثاني.
  • يجب أن يحتوي كلا الاستعلامين على العدد نفسه من الأعمدة، وبالترتيب نفسه، ونوع البيانات نفسه.
  • قد تتضمن نتيجة EXCEPT صفوفًا مكررة. استخدم EXCEPT DISTINCT إذا لم يكن ذلك مرغوبًا.
  • تُنفَّذ عبارات EXCEPT المتعددة من اليسار إلى اليمين إذا لم تُحدَّد أقواس.
  • لعامل EXCEPT أولوية مماثلة لجملة UNION، وأولوية أقل من جملة INTERSECT.

البنية

SELECT column1 [, column2 ]
FROM table1
[WHERE condition]

EXCEPT

SELECT column1 [, column2 ]
FROM table2
[WHERE condition]
يمكن أن يكون الشرط أي تعبير وفقًا لمتطلباتك. بالإضافة إلى ذلك، يمكن استخدام EXCEPT() لاستبعاد الأعمدة من النتيجة في الجدول نفسه، كما هو الحال في BigQuery (Google Cloud)، باستخدام الصيغة التالية:
SELECT column1 [, column2 ] EXCEPT (column3 [, column4]) 
FROM table1 
[WHERE condition]

أمثلة

توضح الأمثلة في هذا القسم كيفية استخدام جملة EXCEPT.

تصفية الأرقام باستخدام جملة EXCEPT

إليك مثالًا بسيطًا يعيد الأرقام من 1 إلى 10 التي لا تقع ضمن الأرقام من 3 إلى 8:
Query
SELECT number
FROM numbers(1, 10)
EXCEPT
SELECT number
FROM numbers(3, 6)
Response
┌─number─┐
│      1 │
│      2 │
│      9 │
│     10 │
└────────┘

استبعاد أعمدة محددة باستخدام EXCEPT()

يمكن استخدام EXCEPT() لاستبعاد الأعمدة من النتيجة بسرعة. على سبيل المثال، إذا أردنا تحديد جميع الأعمدة في جدول ما، باستثناء بعض الأعمدة المحددة، كما هو موضح في المثال أدناه:
Query
SHOW COLUMNS IN system.settings

SELECT * EXCEPT (default, alias_for, readonly, description)
FROM system.settings
LIMIT 5
Response
    ┌─field───────┬─type─────────────────────────────────────────────────────────────────────┬─null─┬─key─┬─default─┬─extra─┐
 1. │ alias_for   │ String                                                                   │ NO   │     │ ᴺᵁᴸᴸ    │       │
 2. │ changed     │ UInt8                                                                    │ NO   │     │ ᴺᵁᴸᴸ    │       │
 3. │ default     │ String                                                                   │ NO   │     │ ᴺᵁᴸᴸ    │       │
 4. │ description │ String                                                                   │ NO   │     │ ᴺᵁᴸᴸ    │       │
 5. │ is_obsolete │ UInt8                                                                    │ NO   │     │ ᴺᵁᴸᴸ    │       │
 6. │ max         │ Nullable(String)                                                         │ YES  │     │ ᴺᵁᴸᴸ    │       │
 7. │ min         │ Nullable(String)                                                         │ YES  │     │ ᴺᵁᴸᴸ    │       │
 8. │ name        │ String                                                                   │ NO   │     │ ᴺᵁᴸᴸ    │       │
 9. │ readonly    │ UInt8                                                                    │ NO   │     │ ᴺᵁᴸᴸ    │       │
10. │ tier        │ Enum8('Production' = 0, 'Obsolete' = 4, 'Experimental' = 8, 'Beta' = 12) │ NO   │     │ ᴺᵁᴸᴸ    │       │
11. │ type        │ String                                                                   │ NO   │     │ ᴺᵁᴸᴸ    │       │
12. │ value       │ String                                                                   │ NO   │     │ ᴺᵁᴸᴸ    │       │
    └─────────────┴──────────────────────────────────────────────────────────────────────────┴──────┴─────┴─────────┴───────┘

   ┌─name────────────────────┬─value──────┬─changed─┬─min──┬─max──┬─type────┬─is_obsolete─┬─tier───────┐
1. │ dialect                 │ clickhouse │       0 │ ᴺᵁᴸᴸ │ ᴺᵁᴸᴸ │ Dialect │           0 │ Production │
2. │ min_compress_block_size │ 65536      │       0 │ ᴺᵁᴸᴸ │ ᴺᵁᴸᴸ │ UInt64  │           0 │ Production │
3. │ max_compress_block_size │ 1048576    │       0 │ ᴺᵁᴸᴸ │ ᴺᵁᴸᴸ │ UInt64  │           0 │ Production │
4. │ max_block_size          │ 65409      │       0 │ ᴺᵁᴸᴸ │ ᴺᵁᴸᴸ │ UInt64  │           0 │ Production │
5. │ max_insert_block_size   │ 1048449    │       0 │ ᴺᵁᴸᴸ │ ᴺᵁᴸᴸ │ UInt64  │           0 │ Production │
   └─────────────────────────┴────────────┴─────────┴──────┴──────┴─────────┴─────────────┴────────────┘

استخدام EXCEPT و INTERSECT مع بيانات العملات المشفّرة

يمكن في كثير من الأحيان استخدام EXCEPT و INTERSECT بالتبادل مع منطق بولياني مختلف، وكلاهما مفيد إذا كان لديك جدولان يشتركان في عمود واحد (أو عدة أعمدة). على سبيل المثال، لنفترض أن لدينا بضعة ملايين من صفوف البيانات التاريخية للعملات المشفّرة التي تتضمن أسعار التداول والحجم:
Query
CREATE TABLE crypto_prices
(
    trade_date Date,
    crypto_name String,
    volume Float32,
    price Float32,
    market_cap Float32,
    change_1_day Float32
)
ENGINE = MergeTree
PRIMARY KEY (crypto_name, trade_date);

INSERT INTO crypto_prices
   SELECT *
   FROM s3(
    'https://learn-clickhouse.s3.us-east-2.amazonaws.com/crypto_prices.csv',
    'CSVWithNames'
);

SELECT * FROM crypto_prices
WHERE crypto_name = 'Bitcoin'
ORDER BY trade_date DESC
LIMIT 10;
Response
┌─trade_date─┬─crypto_name─┬──────volume─┬────price─┬───market_cap─┬──change_1_day─┐
│ 2020-11-02 │ Bitcoin     │ 30771456000 │ 13550.49 │ 251119860000 │  -0.013585099 │
│ 2020-11-01 │ Bitcoin     │ 24453857000 │ 13737.11 │ 254569760000 │ -0.0031840964 │
│ 2020-10-31 │ Bitcoin     │ 30306464000 │ 13780.99 │ 255372070000 │   0.017308505 │
│ 2020-10-30 │ Bitcoin     │ 30581486000 │ 13546.52 │ 251018150000 │   0.008084608 │
│ 2020-10-29 │ Bitcoin     │ 56499500000 │ 13437.88 │ 248995320000 │   0.012552661 │
│ 2020-10-28 │ Bitcoin     │ 35867320000 │ 13271.29 │ 245899820000 │   -0.02804481 │
│ 2020-10-27 │ Bitcoin     │ 33749879000 │ 13654.22 │ 252985950000 │    0.04427984 │
│ 2020-10-26 │ Bitcoin     │ 29461459000 │ 13075.25 │ 242251000000 │  0.0033826586 │
│ 2020-10-25 │ Bitcoin     │ 24406921000 │ 13031.17 │ 241425220000 │ -0.0058658565 │
│ 2020-10-24 │ Bitcoin     │ 24542319000 │ 13108.06 │ 242839880000 │   0.013650347 │
└────────────┴─────────────┴─────────────┴──────────┴──────────────┴───────────────┘
لنفترض الآن أن لدينا جدولًا باسم holdings يتضمن قائمة بالعملات المشفّرة التي نملكها، إلى جانب عدد الوحدات من كل عملة:
Query
CREATE TABLE holdings
(
    crypto_name String,
    quantity UInt64
)
ENGINE = MergeTree
PRIMARY KEY (crypto_name);

INSERT INTO holdings VALUES
   ('Bitcoin', 1000),
   ('Bitcoin', 200),
   ('Ethereum', 250),
   ('Ethereum', 5000),
   ('DOGEFI', 10),
   ('Bitcoin Diamond', 5000);
يمكننا استخدام EXCEPT للإجابة عن سؤال مثل “ما العملات التي نملكها ولم تُتداول قط بأقل من 10 دولارات؟”:
Query
SELECT crypto_name FROM holdings
EXCEPT
SELECT crypto_name FROM crypto_prices
WHERE price < 10;
Response
┌─crypto_name─┐
│ Bitcoin     │
│ Bitcoin     │
└─────────────┘
هذا يعني أنه من بين العملات المشفّرة الأربع التي نملكها، لم تنخفض قيمة Bitcoin وحدها أبدًا إلى أقل من 10 دولارات (استنادًا إلى البيانات المحدودة المتاحة لدينا هنا في هذا المثال).

استخدام EXCEPT DISTINCT

لاحظ أنه في الاستعلام السابق ظهرت في النتيجة عدة حيازات من Bitcoin. يمكنك إضافة DISTINCT إلى EXCEPT لإزالة الصفوف المكررة من النتيجة:
Query
SELECT crypto_name FROM holdings
EXCEPT DISTINCT
SELECT crypto_name FROM crypto_prices
WHERE price < 10;
Response
┌─crypto_name─┐
│ Bitcoin     │
└─────────────┘
راجع أيضًا
آخر تعديل في ٢٥ يونيو ٢٠٢٦