SQLとSQLアドバンスシリーズ7コレクション操作

EDITORIAL

この機能は、また、セット指向のSQL言語として知られているので、セットの理論は、SQL言語の基礎であります

インポート記事:いくつかのノートが操作を設定します

  • 注1:SQLは(マルチセット、バッグ)重複行のセットで動作することができ、すべてのオプションがサポートできます

    ALL SELECT句DISTINCTと逆の効果; SQL演算子許可繰り返し、2つの用途を繰り返す許可のセットを提供し、UNIONとINTERSECTの結果が重複する行に表示されません、UNION ALLは、重複行を保持しています。すべてのヘルプ最適化クエリのパフォーマンス、すべての使用後にノーソート理由

  • 演算子の優先順位のセットが存在する:注2

    標準SQLの規定:INTERSECTおよびUNIONよりも高い優先順位EXCEPT

  • 注3:集合演算上のさまざまなDBMSプロバイダの実現の程度が異なります

    MySQLはOracleがMINUS EXCEPT代替を使用して、サポートしていません。

  • 注4:分割操作の標準的な定義は存在しません

    そして、4つの操作(UNION)、差(EXCEPT)、製品は(CROSS JOINは)標準SQLに導入され、プロバイダはSQL標準を入力するために遅れています

テーブルの比較:記事のコレクションは平等に基づいていることを確認

/* 比较表和表:检查集合相等性 */
CREATE TABLE Tbl_A
 (keycol  CHAR(1) PRIMARY KEY,
  col_1   INTEGER, 
  col_2   INTEGER, 
  col_3   INTEGER);

CREATE TABLE Tbl_B
 (keycol  CHAR(1) PRIMARY KEY,
  col_1   INTEGER, 
  col_2   INTEGER, 
  col_3   INTEGER);

/* 表相等的情况 */
DELETE FROM Tbl_A;
INSERT INTO Tbl_A VALUES('A', 2, 3, 4);
INSERT INTO Tbl_A VALUES('B', 0, 7, 9);
INSERT INTO Tbl_A VALUES('C', 5, 1, 6);

DELETE FROM Tbl_B;
INSERT INTO Tbl_B VALUES('A', 2, 3, 4);
INSERT INTO Tbl_B VALUES('B', 0, 7, 9);
INSERT INTO Tbl_B VALUES('C', 5, 1, 6);

/* B行不同的情况 */
DELETE FROM Tbl_A;
INSERT INTO Tbl_A VALUES('A', 2, 3, 4);
INSERT INTO Tbl_A VALUES('B', 0, 7, 9);
INSERT INTO Tbl_A VALUES('C', 5, 1, 6);

DELETE FROM Tbl_B;
INSERT INTO Tbl_B VALUES('A', 2, 3, 4);
INSERT INTO Tbl_B VALUES('B', 0, 7, 8);
INSERT INTO Tbl_B VALUES('C', 5, 1, 6);

/* 包含NULL的情况(相等) */
DELETE FROM Tbl_A;
INSERT INTO Tbl_A VALUES('A', NULL, 3, 4);
INSERT INTO Tbl_A VALUES('B', 0, 7, 9);
INSERT INTO Tbl_A VALUES('C', NULL, NULL, NULL);

DELETE FROM Tbl_B;
INSERT INTO Tbl_B VALUES('A', NULL, 3, 4);
INSERT INTO Tbl_B VALUES('B', 0, 7, 9);
INSERT INTO Tbl_B VALUES('C', NULL, NULL, NULL);

/* 包含NULL的情况(C行不同) */
DELETE FROM Tbl_A;
INSERT INTO Tbl_A VALUES('A', NULL, 3, 4);
INSERT INTO Tbl_A VALUES('B', 0, 7, 9);
INSERT INTO Tbl_A VALUES('C', NULL, NULL, NULL);

DELETE FROM Tbl_B;
INSERT INTO Tbl_B VALUES('A', NULL, 3, 4);
INSERT INTO Tbl_B VALUES('B', 0, 7, 9);
INSERT INTO Tbl_B VALUES('C', 0, NULL, NULL);

UNION B = A = B:同じ2つのテーブル、以下の論理であれば 、 また、(\ \カップ\) B = A \(\ CAP \) B

-- 判断两表是否完全相等(判断之前可以看看行数相不相同)
SELECT COUNT(*) AS row_cnt FROM 
((SELECT * FROM Tbl_A ) 
UNION 
(SELECT * FROM Tbl_B)) AS Total;

S UNION S = Sはこれが冪等と呼ばれ、プラス何回結果の同じセットが同じである:上記の表に、我々は、任意のSテーブルを持っているため、以下の式が成り立つことがわかります。

テーブルの比較:平等のコレクションは、高度なことを確認してください記事

二組を分析することは集合論、以下の2つの一般的な方法が同じです:

  • \(\サブセット\) B且A \(\ supsetの\) B \(\ Leftrightarrow \) A = B
  • \(\カップ\) B = A \(\キャップ\) B \(\ Leftrightarrow \) A = B
-- A union B = A intersect B means A = B,不难发现intersect也是一个幂等运算符
-- 两张表相等时返回"相等",否则返回"不相等"
SELECT CASE WHEN COUNT(*) = 0 
            THEN '相等' ELSE '不相等' END AS result
FROM ((SELECT * FROM tbl_A) UNION (SELECT * FROM tbl_B) 
      EXCEPT 
      (SELECT * FROM tbl_A) INTERSECT (SELECT * FROM tbl_B)) AS TMP;
-- 查看量表不一样的记录
(SELECT * FROM Tbl_A EXCEPT SELECT * FROM Tbl_B)
UNION ALL
(SELECT * FROM Tbl_B EXCEPT SELECT * FROM Tbl_A);

差動電流分割を達成するための関係

  • ネストされていないがEXISTS
  • HAVING句を使用すると、1人の関係に変換され、
  • 繰り返しは減算となり
-- 建表语句
/* 用差集实现关系除法运算 */
CREATE TABLE Skills 
(skill VARCHAR(32),
 PRIMARY KEY(skill));

CREATE TABLE EmpSkills 
(emp   VARCHAR(32), 
 skill VARCHAR(32),
 PRIMARY KEY(emp, skill));

INSERT INTO Skills VALUES('Oracle');
INSERT INTO Skills VALUES('UNIX');
INSERT INTO Skills VALUES('Java');

INSERT INTO EmpSkills VALUES('相田', 'Oracle');
INSERT INTO EmpSkills VALUES('相田', 'UNIX');
INSERT INTO EmpSkills VALUES('相田', 'Java');
INSERT INTO EmpSkills VALUES('相田', 'C#');
INSERT INTO EmpSkills VALUES('神崎', 'Oracle');
INSERT INTO EmpSkills VALUES('神崎', 'UNIX');
INSERT INTO EmpSkills VALUES('神崎', 'Java');
INSERT INTO EmpSkills VALUES('平井', 'UNIX');
INSERT INTO EmpSkills VALUES('平井', 'Oracle');
INSERT INTO EmpSkills VALUES('平井', 'PHP');
INSERT INTO EmpSkills VALUES('平井', 'Perl');
INSERT INTO EmpSkills VALUES('平井', 'C++');
INSERT INTO EmpSkills VALUES('若田部', 'Perl');
INSERT INTO EmpSkills VALUES('渡来', 'Oracle');
-- 用求差集的方法进行关系除法运算(有余数)
SELECT DISTINCT emp 
FROM EmpSkills ES1
WHERE NOT EXISTS 
(SELECT skill FROM Skills EXCEPT SELECT skill FROM EmpSkills ES2 WHERE ES1.emp = ES2.emp);

同等のサブセットを探して

/* 4.寻找相等的子集 */
CREATE TABLE SupParts
(sup  CHAR(32) NOT NULL,
 part CHAR(32) NOT NULL,
 PRIMARY KEY(sup, part));

INSERT INTO SupParts VALUES('A',  '螺丝');
INSERT INTO SupParts VALUES('A',  '螺母');
INSERT INTO SupParts VALUES('A',  '管子');
INSERT INTO SupParts VALUES('B',  '螺丝');
INSERT INTO SupParts VALUES('B',  '管子');
INSERT INTO SupParts VALUES('C',  '螺丝');
INSERT INTO SupParts VALUES('C',  '螺母');
INSERT INTO SupParts VALUES('C',  '管子');
INSERT INTO SupParts VALUES('D',  '螺丝');
INSERT INTO SupParts VALUES('D',  '管子');
INSERT INTO SupParts VALUES('E',  '保险丝');
INSERT INTO SupParts VALUES('E',  '螺母');
INSERT INTO SupParts VALUES('E',  '管子');
INSERT INTO SupParts VALUES('F',  '保险丝');
-- 生成供应商的全部组合
SELECT SP1.sup AS s1,SP2.sup AS s2
FROM SupParts SP1,SupParts SP2
WHERE SP1.sup < SP2.sup
GROUP BY SP1.sup,SP2.sup;
SELECT SP1.sup AS s1,SP2.sup AS s2
FROM SupParts SP1,SupParts SP2
WHERE SP1.sup < SP2.sup
AND SP1.part = SP2.part
GROUP BY SP1.sup,SP2.sup
HAVING COUNT(*) = (SELECT COUNT(*) FROM SupParts SP3 WHERE SP3.sup = SP1.sup)
AND COUNT(*) = (SELECT COUNT(*) FROM SupParts SP4 WHERE SP4.sup = SP2.sup);

効率的なSQLの重複行を削除

/* 5.用于删除重复行的高效SQL */
/* 在PostgreSQL中,需要把“with oids”添加到CREATE TABLE语句的最后 */
CREATE TABLE Products
(name  CHAR(16),
 price INTEGER);

INSERT INTO Products VALUES('苹果',  50);
INSERT INTO Products VALUES('橘子', 100);
INSERT INTO Products VALUES('橘子', 100);
INSERT INTO Products VALUES('橘子', 100);
INSERT INTO Products VALUES('香蕉',  80);
-- 删除重复行:使用关联子查询
DELETE FROM Products
WHERE rowid < (SELECT MAX(P2.rowid) FROM Products P2 WHERE Products.name = P2.name AND Product.price = P2.price);
-- 用于删除重复行的高效SQL语句(1):通过EXCEPT求补集
DELETE FROM Products
WHERE rowid IN (SELECT rowid FROM Products EXCEPT SELECT MAX(rowid) FROM Products GROUP BY name,price)
-- 用于删除重复行的高效SQL语句(2):通过NOT IN求补集
DELETE FROM Products
WHERE rowid  NOT IN (SELECT MAX(rowid) FROM Products GROUP BY name,price)

概要

  • 集合演算の利用規約は、SQLの標準化は、非常にゆっくりと行って、使用するときに注意を払う必要があります
  • あなたはALL集合演算子オプションを指定しない場合、重複行は除外されるが、また、ソートは、この場合に起こったので、パフォーマンスが十分ではありません
  • 冪等ではありませんEXCEPTながらUNIONとINTERSECTは、冪等です
  • 標準SQLには、除算演算子を実装する必要がある問題ではありません
  • 等しい二組を分析して、1つのマッピングは、2つの電源によって方法等であってもよいです
  • 単純に補完することができるEXCEPT使い方

演習

/* 练习题1-7-1:改进“只使用UNION的比较” */
SELECT CASE WHEN COUNT(*) = (SELECT COUNT(*) FROM tbl_A )
             AND COUNT(*) = (SELECT COUNT(*) FROM tbl_B )
            THEN '相等'
            ELSE '不相等' END AS result
  FROM ( SELECT * FROM tbl_A
         UNION
         SELECT * FROM tbl_B ) TMP;
/* 练习题1-7-2:精确关系除法运算 */
SELECT DISTINCT emp
  FROM EmpSkills ES1
 WHERE NOT EXISTS
        (SELECT skill
           FROM Skills
         EXCEPT
         SELECT skill
           FROM EmpSkills ES2
          WHERE ES1.emp = ES2.emp)
  AND NOT EXISTS
        (SELECT skill
           FROM EmpSkills ES3
          WHERE ES1.emp = ES3.emp
         EXCEPT
         SELECT skill
           FROM Skills );
/* 练习题1-7-2:精确关系除法运算 */
SELECT emp
  FROM EmpSkills ES1
 WHERE NOT EXISTS
        (SELECT skill
           FROM Skills
         EXCEPT
         SELECT skill
           FROM EmpSkills ES2
          WHERE ES1.emp = ES2.emp)
 GROUP BY emp
HAVING COUNT(*) = (SELECT COUNT(*) FROM Skills);

おすすめ

転載: www.cnblogs.com/evian-jeff/p/11580818.html