データベースの紹介_06

データベースプラットフォーム間でのページング表示

実際にデータを表示する場合、一度にすべてのデータをロードすることはできませんので、オンデマンドロードを使用することをお勧めします。

public class App2 {
    
    
	public static void main(String[] args) {
    
    
		// 显示第5页数据,每页10条数据
		int pageNum = 5;
		int rowsPerPage = 10;
		List<Student> res = new ArrayList<>();
		try (Connection conn = DriverManager.getConnection("jdbc:mysql:///test?serverTimezone=UTC", "root", "123456")) {
    
    
			// 如果考虑跨数据库平台,这里的sql应该使用标准sql
			String sql = "select * from tb_student";
			PreparedStatement ps = conn.prepareStatement(sql,
			ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
			ResultSet rs = ps.executeQuery();
			// 需要判断页码值的合理性,页码值需要大于0,小于等于最大页码值
			// 如果页码值小于1,则为1;如果大于最大页码值则为最大页码值
			if (rs.last()) {
    
     //将行指针移动到最后一行
				int rowNum = rs.getRow(); // 获取总行数
				int maxPage = rowNum / rowsPerPage;
				if (rowNum % rowsPerPage != 0)
					maxPage++;
				if (pageNum < 1)
					pageNum = 1;
				if (pageNum > maxPage)
					pageNum = maxPage;
				int begin = (pageNum - 1) * rowsPerPage + 1;// 起始行号
				rs.absolute(begin);// 将行指针移动到指定的行上
				int count = 0;
				do {
    
    
					Student s = new Student();
					s.setId(rs.getLong("id"));
					s.setName(rs.getString("name"));
					res.add(s);
					count++;
					if (count >= rowsPerPage)
						break;
				} while (rs.next());
			}
		} catch (Exception e) {
    
    
			e.printStackTrace();
		}
		for (Student tmp : res)
			System.out.println(tmp);
	}
}

class Student implements Serializable {
    
    
	private Long id;
	private String name;
	
	public Long getId() {
    
    
		return id;
	}
	
	public void setId(Long id) {
    
    
		this.id = id;
	}
	
	public String getName() {
    
    
		return name;
	}
	
	public void setName(String name) {
    
    
		this.name = name;
	}
	
	@Override
	public String toString() {
    
    
		return "Student [id=" + id + ", name=" + name + "]";
	}
}

変更可能な結果セット

パフォーマンスの問題のため、通常は使用をお勧めしません。

// MySQL驱动支持JDBC4
try (Connection conn = DriverManager.getConnection("jdbc:mysql:///test?serverTimezone=UTC", "root", "123456")) {
    
    
	PreparedStatement ps = conn.prepareStatement("select * from tb_student",ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);
	ResultSet rs = ps.executeQuery();
	//获取第3行数据
	rs.absolute(3);
	//在当前行上执行修改指定列数据的操作
	rs.updateString("name","东方星雨");
	rs.updateRow();//修改修改
	// 插入数据
	rs.moveToInsertRow();//将结果集指针移动到插入行上
	rs.updateString("name","张三");
	rs.insertRow();//插入数据
	//删除当前行数据,删除第5行数据
	rs.absolute(5);
	rs.deleteRow();//删除当前行
	rs.close();
	ps.close();
}

特別なプレースホルダ

  • ファジークエリ、select * from t_user where username like '%a%';
    使用concat('%a%')
    select * from t_user where username like concat('%',?,'%')
  • 一括削除String ids = "1,2,3"; delete from t_user where id in('1,2,3');
    • 方法 1:inと文字列の連結を使用します。String ids = "1,2,3";、SQLを実行しますString sql="delete from t_user where id in(" + ids + ")";
    • 方法 2: を使用しor1 = 1orを使用します1 != 1
      。 where の条件判断では、1 = 1より良い接続and条件を使用し、1 != 1より良い接続or条件を使用し
      て次のような結果を表示できます。delete from t_user where 1!=1 or id = 1 or id = 2 or id = 3

データテーブルのメタデータを取得する

ResultSetMetaData オブジェクトは、すべての ResultSet オブジェクトのフィールドに関する情報を保存し、フィールド関連情報を取得するための対応するメソッドを提供します。

  • int getColumnCount() ResultSet オブジェクト内のフィールドの数を取得します。
  • String getColumnName(int index) ResultSet オブジェクト内の指定されたシリアル番号に対応するフィールドの名前を取得します。

テーブルのメタデータ情報を取得する

ResultSet rs=ps.executeQuery();
ResultSetMetaData rsmd= rs.getMetaData();
int len=rsmd.getColumnCount();//获取列数
for(int i=1;i<=len;i++){
    
    
	String columnName=rsmd.getColumnName(i);//获取列名称
	String typeName=rsmd.getColumnTypeName(i);//获取列的类型名称
	System.out.println(columnName+"\t"+typeName);
}

SQL例外

JDBC API メソッドを呼び出すときにチェック例外/非ランタイム例外が発生することがよくあり、コーディング中に例外を処理する必要があります。ただし、SQL ステートメントの構文エラーや Connection オブジェクトを閉じるときのエラーなど、ほとんどの例外はコーディングでは解決できません。さらに、SQLException の粒度は粗すぎて、例外の原因を明確に表現できません。

したがって、一般的な解決策は 2 つあります。 1. 例外を上向きにスローするか、エラー メッセージを記録します。2. SQLException をランタイム例外に変換し、上位レベルの呼び出し元によって処理されます。

限界

MySQL は、部分データを取得するためのキーワード制限を提供します。これは、クエリ結果セット内の部分データを取得するために使用できます。
たとえば、最初の 10 個のデータを取得するために使用できます。select * from tb_student limit 10;

  • 実際には以下と同等ですselect * from tb_student limit 0,10

5行目から3つのデータを取得select * from tb_student limit 5-1,3;

  • 行数は0から始まります

意見

共通データベースオブジェクト

物体 説明
テーブル テーブル テーブルはデータを格納するための論理単位であり、行と列の形式で存在します。列はフィールド、行はレコードです。
データディクショナリ これはシステム テーブル、データベース関連の情報を格納するテーブルです。システム テーブル内のデータは通常、データベース システムによって維持され、プログラマはそれを変更せず、表示するだけにしてください。
制約 データ検証を実行するためのルール、データの整合性を確保するためのルール
見る 見る 1 つ以上のデータ テーブル内のデータの論理表示。ビューにはデータは保存されません。
インデックス INDEX クエリのパフォーマンスを向上させるために使用されます。書籍のディレクトリに相当します。
ストアド プロシージャPROCEDURE 完全なビジネス プロセスを完了するために使用され、戻り値はありませんが、送信パラメータを通じて複数の値を呼び出し環境に渡すことができます。
ストアドファンクション FUNCTION 戻り値を使用して特定の計算を完了するために使用されます。
トリガー TRIGGER イベント リスナーと同等で、データベース内で特定のイベントが発生すると、トリガーがトリガーされて対応する処理を完了します。

概要を表示

このビューは、すべてのテーブルではなくテーブルの一部を使用するのに役立つ一方で、異なるユーザーに対して異なるクエリ ビューを作成することもできます。たとえば、会社の営業スタッフはデータの一部だけを見せたいと考えており、購入価格などの一部の特別なデータは提供されません。もう 1 つの例は、人事給与は機密フィールドであるため、特定のレベル以上の従業員のみに公開されており、このフィールドは他の人のクエリ ビューには提供されません。

見解を理解する

ビューはデータ自体を持たず、メモリ領域をほとんど占有しない仮想テーブルであり、SQL における重要な概念です。
ビューは既存のテーブルに基づいて構築され、ビューが構築されるこれらのテーブルはベース テーブルと呼ばれます。
ここに画像の説明を挿入
ビューの作成と削除はビュー自体にのみ影響し、対応するベーステーブルには影響しません。ただし、ビュー内のデータを追加、削除、変更すると、それに応じてデータ テーブル内のデータも変更され、その逆も同様です。

  • データコンテンツをビューに提供するステートメントは SELECT ステートメントであり、ビューはストアド SELECT ステートメントとして理解できます。
  • データベースでは、ビューはデータを保存せず、データは実際にはデータ テーブルに保存されます。ビュー内のデータを追加、削除、変更すると、それに応じてデータ テーブル内のデータが変更され、その逆も同様です。
  • ビューは、ベース テーブル データをユーザーに提示する別の形式です。ビュー自体を削除しても、ベーステーブル内のデータは削除されません。
  • ビューの適用シナリオ: ビューは小規模プロジェクトには推奨されません。大規模なプロジェクトの場合は、ビューの使用を検討してください。
  • ビューの利点: クエリの簡素化、データへのアクセスの制御
    • ビューは、頻繁にクエリされる結果セットを仮想テーブルに配置するのに役立ち、使用効率が向上し、理解して使用するのに非常に便利です。

ビューの作成

ビューの作成

CREATE [OR REPLACE] [ALGORITHM = {
   
   UNDEFINED | MERGE | TEMPTABLE}] VIEW 视图名称
[(字段列表)]
AS
查询语句 [WITH [CASCADED|LOCAL] CHECK OPTION]

ライトCREATE VIEW 视图名称 AS 查询语句

単一のテーブルビューを作成する

CREATE VIEW empvu80
AS
SELECT employee_id, last_name, salary FROM employees WHERE department_id = 80;

CREATE VIEW emp_year_salary (ename,year_salary)
AS
SELECT ename,salary*12*(1+IFNULL(commission_pct,0)) FROM t_employee;

説明 1: 実際、ビュー VIEW は SQL クエリ ステートメントに基づいてカプセル化されるため、SQL ステートメントの結果セットに基づいて仮想テーブルが形成されます。

注 2: ビューを作成するときに、ビュー名の後にフィールド リストを指定しない場合、ビュー内のフィールド リストはデフォルトで SELECT ステートメントのフィールド リストと同じになります。フィールドが SELECT ステートメントでエイリアス化されている場合、ビュー内のフィールド名はエイリアスと同じになります。

マルチテーブルユニオンビュー

CREATE VIEW empview
AS
SELECT employee_id emp_id,last_name NAME,department_name
FROM employees e,departments d
WHERE e.department_id = d.department_id;


CREATE VIEW dept_sum_vu (name, minsal, maxsal, avgsal)
AS
SELECT d.department_name, MIN(e.salary), MAX(e.salary),AVG(e.salary)
FROM employees e, departments d
WHERE e.department_id = d.department_id GROUP BY d.department_name;

ビューを使用してデータをフォーマットする

多くの場合、コンテンツを特定の形式で出力する必要があります。従業員名と対応する部門名を出力する場合、対応する形式は です。ビューを使用してデータの書式設定操作を完了できますemp_name( department_name)

CREATE VIEW emp_depart
AS
SELECT CONCAT(last_name,'(',department_name,')') AS emp_dept
FROM employees e JOIN departments d
WHERE e.department_id = d.department_id

ビューを作成した後は、それに基づいてビューの作成を続けることができます。例 emp_dept ビューと
emp_year_salary ビューを結合して、従業員名、部門名、および年収情報をクエリし、emp_dept_ysalary ビューを作成します。

CREATE VIEW emp_dept_ysalary
AS
SELECT emp_dept.ename,dname,year_salary
FROM emp_dept INNER JOIN emp_year_salary
ON emp_dept.ename = emp_year_salary.ename;

ビュービュー

構文 1: データベースのテーブル オブジェクトおよびビュー オブジェクトを表示するSHOW TABLES;
構文 2: ビューの構造を表示するDESC / DESCRIBE 视图名称;
構文 3: ビューの属性情報を表示する

# 查看视图信息(显示数据表的存储引擎、版本、数据行数和数据大小等)
SHOW TABLE STATUS LIKE '视图名称'\G

実行結果は、Comment が VIEW でテーブルがビューであることを示し、その他の情報が NULL で仮想テーブルであることを示しています。
構文4: ビューの詳細な定義情報を表示するSHOW CREATE VIEW 视图名称;

ビューデータを更新する

MySQL は、ビュー内のデータを挿入、更新、削除するための INSERT、UPDATE、および DELETE ステートメントの使用をサポートしています。ビュー内のデータが変更されると、データ テーブル内のデータも変更され、その逆も同様です。

UPDATE emp_tel SET tel = '13789091234' WHERE ename = 'yanjun';

DELETE FROM emp_tel WHERE ename = 'yanjun';

更新不可能なビュー

ビューを更新可能にするには、ビュー内の行と基礎となるベース テーブル内の行の間に 1 対 1 の関係が存在する必要があります。さらに、ビュー定義に次の条件がある場合、ビューは更新操作をサポートしません。

  • ビューを定義するときに「ALGORITHM = TEMPTABLE」が指定されている場合、ビューは INSERT および DELETE 操作をサポートしません。
  • ビューには、ベース テーブル内の非 null として定義され、デフォルト値が指定されていない列がすべて含まれているわけではありません。また、ビューは INSERT 操作をサポートしません。
  • ビューを定義する SELECT ステートメントで JOIN クエリが使用されている場合、ビューは INSERT および DELETE 操作をサポートしません。
  • ビューを定義する SELECT ステートメントの後のフィールド リストで数式またはサブクエリが使用されている場合、ビューは数式またはサブクエリを使用したフィールド値の INSERT または UPDATE をサポートしません。
  • ビューを定義する SELECT ステートメントの後のフィールド リストで DISTINCT、集計関数、GROUP BY、HAVING、UNION などを使用すると、ビューは INSERT、UPDATE、DELETE をサポートしません。
  • ビューを定義する SELECT ステートメントにサブクエリが含まれており、FROM の背後にあるテーブルがサブクエリで参照されている場合、ビューは INSERT、UPDATE、DELETE をサポートしません。
  • ビュー定義は更新不可能なビューに基づいています。
  • 一定のビュー。
CREATE OR REPLACE VIEW emp_dept (ename,salary,birthday,tel,email,hiredate,dname)
AS
SELECT ename,salary,birthday,tel,email,hiredate,dname
FROM t_employee INNER JOIN t_department
ON t_employee.did = t_department.did ;

ビューを定義する SELECT ステートメントで JOIN クエリが使用されている場合、ビューは更新操作をサポートしません。

ビュー データは更新できますが、一般に、ビューは主にクエリを容易にするために使用される仮想テーブルであるため、ビュー データを更新することはお勧めできません。ビュー データへの変更はすべて、実際のデータ テーブル内のデータに対する操作を通じて行われます。

ビューを変更する

方法 1: CREATE OR REPLACE VIEW 句を使用してビューを変更する
注: CREATE VIEW 句内の列の別名は、サブクエリ内の列に対応する必要があります。

CREATE OR REPLACE VIEW empvu80 (id_number, name, sal, department_id)
AS
SELECT employee_id, first_name || ' ' || last_name, salary, department_id
FROM employees WHERE department_id = 80;

注: CREATE VIEW 句内の列の別名は、サブクエリ内の列に対応する必要があります。

方法 2: ALTER VIEW を使用してビューを変更するALTER VIEW 视图名称 AS 查询语句

ビューの削除

ビューを削除すると、ビューの定義が削除されるだけで、ベース テーブル内のデータは削除されません。
ビューを削除するための構文は次のとおりです。DROP VIEW IF EXISTS 视图名称;

説明: ビュー a および b に基づいて新しいビュー c が作成されます。ビュー a またはビュー b が削除されると、ビュー c のクエリは失敗します。このようなビュー c は手動で削除または変更する必要があります。そうしないと、使用に影響します。

利点を見る

1. 簡単な操作。よく使用するクエリ操作をビューとして定義することで、開発者はビューに対応するデータテーブルの構造やテーブル間の関係、データテーブル間のビジネスロジックやクエリ条件を意識することなく、単純にビューを操作するだけで済みます。開発者のデータベース操作が大幅に簡素化されます。

2. データの冗長性を削減します。ビューは実際のデータ テーブルとは異なり、クエリ ステートメントを格納します。したがって、使用する場合はビューのクエリ文を定義して結果セットを取得する必要があります。ビュー自体はデータを保存せず、データ ストレージ リソースを占有せず、データの冗長性を軽減します。

3. データのセキュリティ。MySQL は、ユーザーのデータへのアクセスを特定のデータの結果セットに制限しており、これらのデータの結果セットはビューを使用して実現できます。ユーザーはデータテーブルを直接クエリしたり操作したりする必要はありません。これはビューの分離としても理解できます。このビューは、ユーザーと実際のデータ テーブルの間に仮想テーブルのレイヤーを追加することに相当します。

同時に、MySQL はユーザーのデータへのアクセスを権限に応じて特定のビューに制限することができ、ユーザーはデータ テーブルにクエリを実行する必要がなく、ビューを通じてデータ テーブル内の情報を直接取得できます。これにより、データ テーブル内のデータのセキュリティがある程度保証されます。

4. 柔軟で変化するニーズに適応します。業務システムの要件が変化した場合、データテーブルの構造を変更する必要がある場合、作業負荷は比較的大きくなりますが、ビューを使用することで変更の作業負荷を軽減できます。実際の仕事ではこの方法がよく使われます。

5. 複雑なクエリロジックを分解する機能。データベースに複雑なクエリ ロジックがある場合は、問題を分解し、複数のビューを作成してデータを取得し、作成した複数のビューを結合して複雑なクエリ ロジックを完成させることができます。

実際のデータ テーブルに基づいてビューが作成されている場合、実際のデータ テーブルの構造が変更された場合、適切なタイミングで関連するビューを保守する必要があります。特に、入れ子になったビュー (つまり、ビューを基にしてビューを作成する) の場合、メンテナンスが複雑になり、可読性も悪く、システムの隠れた危険になりやすくなります。ビューを作成する SQL クエリにはフィールドの名前が変更されたり、複雑なロジックが含まれたりする可能性があり、メンテナンスのコストが増加するためです。そのため、実際のプロジェクトではビュー数が多すぎるとデータベースの維持コストが問題となります。

ビューを作成する際には、実際のプロジェクト要件を組み合わせ、ビューの長所と短所を総合的に考慮して、ビューを正しく使用し、システム全体を最適化する必要があります。

関数

関数はコンピューター言語を使用するあらゆる場面で使用されますが、関数の役割は何ですか? 頻繁に使用されるコードをカプセル化し、必要に応じて直接呼び出すことができます。これにより、コードの効率が向上するだけでなく、保守性も向上します。SQL で関数を使用して、取得したデータに対して関数操作を実行することもできます。これらの機能を利用することで、ユーザーのデータベース管理効率が大幅に向上します。
ここに画像の説明を挿入
関数定義の観点から、関数は組み込み関数とカスタム関数に分類できます。SQL 言語には、組み込み関数とユーザー定義関数も含まれます。組み込み関数はシステムに組み込まれている汎用関数ですが、カスタム関数は独自のニーズに応じて作成されます。

機能説明

SQL 言語を使用する場合、この言語を直接扱うのではなく、別のデータベース ソフトウェア、つまり DBMS を使用します。DBMS 間の違いは非常に大きく、同じ言語の異なるバージョン間の違いよりもはるかに大きくなります。実際、DBMS で同時にサポートされる機能はわずかです。たとえば、ほとんどの DBMS は連結文字として || または + を使用しますが、MySQL の文字列連結関数は concat() です。ほとんどの DBMS には独自の関数があり、SQL 関数を使用するコードの移植性が非常に低いため、関数を使用する場合は特に注意する必要があります。

MySQL は、データの保守と管理をより便利にし、データ分析と統計機能をより適切に提供し、開発者のデータ分析と統計の効率をある程度向上させる豊富な組み込み関数を提供します。

MySQL が提供する組み込み関数は、実現される機能の観点から数値関数、文字列関数、日時関数、フロー制御関数、暗号化・復号化関数、MySQL 情報取得関数、集計関数などに分類できます。ここで、これらの豊富な組み込み関数は、単一行関数、集計関数 (またはグループ化関数) の 2 つのカテゴリにさらに分類されます。

2 つの SQL 関数

ここに画像の説明を挿入

一行関数

  • データオブジェクトの操作
  • パラメータを受け取り、結果を返します
  • 1行だけを変換する
  • 行ごとに 1 つの結果を返します
  • 入れ子にすることができます
  • パラメータには列または値を指定できます

複数行の関数

集計関数とも呼ばれる複数行関数は、行のグループ化を操作し、各グループの結果を返します。クエリでグループ化が指定されていない場合、クエリの結果はグループとして扱われます。

集計関数の種類には主に、平均平均値、カウント数、最大最大値、最小最小値、合計が含まれます。

すべての集計関数は null 値を無視します (処理しません)。ifnull 関数または coalesce 関数を使用して null 値を値に置き換えることができ、distinct を使用してクエリされたデータの重複を排除できます。

集計関数を相互にネストすることはできません。

文法select 函数名称(); 或者 select 函数名称(列名称,其它参数) from 表名称、mysql では from 句は必要ありません

名前 説明
腹筋() 絶対値を返す
ランド() ランダムな浮動小数点値を返します
+ - 数値に変換して計算しようとしても0には変換できません
シーリング() 引数以上の最小の整数値を返します。
床() 引数以下の最大の整数値を返します。
length() と char_length() 文字列の長さをバイト単位で返します。
substr(s,index,len) 文字列 s のインデックス位置から len 文字を返します。
left (インターセプトされた文字列、インターセプトされた長さ) 指定された数の左端の文字を返します、SELECT LEFT('www.lanou3g.com',8)
右() 指定された数の右端の文字を返します
トリム() 先頭と末尾のスペースを削除する
curdate() 現在の日付を返す
concat(列1、列2、...) 連結された文字列を返します
ifnull(列名,'デフォルト')
フォーマット() 指定された小数点以下の桁数にフォーマットされた数値を返します (select format(salary,1); 四捨五入)
日付形式(d,f) 式 f select date_format(now(), '%Y-%m-%d') で必要な日付を表示します。
今() 現在の日付と時刻を返します
uuid() 普遍的に一意の識別子を返す
ユーザー() クライアントによって提供されたユーザー名とホスト名
データベース() デフォルト (現在の) データベース名を返します。
  • CONCAT(A, B) – 2 つの文字列値を連結して 1 つの文字列出力を作成します。通常、2 つ以上のフィールドを 1 つに結合するために使用されます。
  • LENGTH(str) は文字列の長さをバイト単位で取得し、CHAR_LENGTH 関数は文字列の長さを取得して文字数の長さを計算します。
  • FORMAT(X, D) - 数値 X を有効数字 D にフォーマットします。

FOMRAT(N,D,locale); 数値 N を、小数点以下 D 桁に四捨五入した「#,###,###.##」などの形式にフォーマットします。
値を文字列として返します。ここで、N はフォーマットする数値です。D は四捨五入する小数点以下の桁数です。locale は、
千の位の区切り文字と区切り文字間のグループ化を決定するオプションのパラメータです。ロケール演算子が省略された場合、MySQL はデフォルト
で en_US になります。
SELECT FORMAT(14500.2018, 2); 14,500.20 を返します

  • CURDATE()、CURTIME() - 現在の日付または時刻を返します。

  • NOW() – 現在の日付と時刻を値として返します。また、MONTH()、DAY()、YEAR()、
    WEEK()、WEEKDAY() - 日付値から指定されたデータを抽出します。HOUR()、MINUTE()、
    SECOND() - 時間値から指定されたデータを抽出します。

  • DATEDIFF(A,B) - 2 つの日付間の日数の差を求めます。年齢の計算によく使用されます。

SELECT DATEDIFF('2008-12-29','2008-12-30') AS DiffDate
ROUND(DATEDIFF(requiredDate, orderDate) / 365, 1) 小数点第 1 位に四捨五入

  • SUBTIMES(A,B) – 時間の減算を実行するために使用されます。

SUBTIME('2018-10-31 23:59:59','0:1:1') は 2018-10-31 23:58:58 を返します

  • FROM_DAYS(INT) – 整数の日数を日付値に変換します。

TO_DAYS(date) 日付を指定すると、日数 (年 0 からの日数) を返します。
SELECT TO_DAYS('1997-10-07'); -> 729669
FROM_DAYS(N) 日数 N を指定すると、 DATE 値
SELECT FROM_DAYS(729669); -> '1997-10-07'

  • IFNULL() 関数は、最初の式が NULL かどうかを判断するために使用され、NULL の場合は 2 番目のパラメーターの値を返し、NULL でない場合は最初のパラメーターの値を返します。

SELECT IFNULL(価格,0.0);

集計関数

集計関数はデータのセットを操作し、そのデータのセットの値を返します。

集計関数の種類: AVG()、SUM()、MAX()、MIN()、COUNT()

  • 数値データに対して AVG 関数と SUM 関数を使用できます。
  • MIN 関数と MAX 関数は、任意のデータ型のデータに使用できます。
  • COUNT(*) は、テーブル内のレコードの合計数を返します。これは、任意のデータ型に適用できます。
  • COUNT(expr) は、expr が空ではないレコードの総数を返します。

質問 1: count( )、count(1)、または count (列名) を使用するのはどれが適切ですか?
実際、MyISAM エンジンのテーブル間に違いはありません。このエンジン内には行数を維持するためのカウンターがあります。
Innodb エンジン テーブルは count(
)、count(1) を使用して行数を直接読み取りますが、innodb は実際に再度カウントする必要があるため、複雑さは O(n) です
ただし、特定の count (列名) の質問よりも優れています
: count ( ) の代わりに count (列名) を使用できますか?
count ( ) の代わりに count (列名) を使用しないでください
、count ( ) は標準の統計行ですSQL92 構文で定義された数値。データベース
とは関係が
なく、NULL と非 NULL も関係ありません。
説明: count(

) は、特定の列で値が NULL である行をカウントしますが、count (列名) は、この列で値が NULL である行をカウントしません。

グループ操作

テーブル内のデータは、GROUP BY 句を使用してグループに分割できます。

SELECT column, group_function(column) FROM table
[WHERE condition]
[GROUP BY group_by_expression]
[ORDER BY column];
  • クリア: WHERE は FROM の後に配置する必要があります。where がある場合は、group by を where の後ろに配置する必要があります。
  • グループ関数に含まれていない SELECT リスト内のすべての列は、GROUP BY 句に含める必要があります。
    • select sex,avg(salary) from tb_users group by sex 正确
    • 性別ごとに tb_users グループからユーザー名、最大 (給与) を選択する構文エラー

拡張子: 特殊な使用法。WITH ROLLUP キーワードを使用した後、クエリされたすべてのグループ レコードの後に​​レコードを追加します。これにより、クエリされたすべてのレコードの合計、つまり統計レコードの数が計算されます。

SELECT department_id,AVG(salary) FROM employees
WHERE department_id > 80
GROUP BY department_id WITH ROLLUP;

注: ROLLUP を使用する場合、ORDER BY 句を使用して結果を同時に並べ替えることはできません。つまり、ROLLUP と ORDER BY は相互に排他的です。

パケットフィルタリング HAVING

  • 行がグループ化されている
  • 集計関数が使われている
  • HAVING句の条件を満たすグループが表示されます
  • HAVING は単独で使用できません。GROUP BY と一緒に使用する必要があります。
SELECT department_id, MAX(salary) FROM employees
GROUP BY department_id
HAVING MAX(salary)>10000
  • 集計関数の不正な使用: 集計関数は WHERE 句で使用できません
SELECT department_id, AVG(salary) FROM employees WHERE
AVG(salary) > 8000
GROUP BY department_id;

WHERE と HAVING の比較

  • 違い 1: WHERE はテーブル内のフィールドをフィルター条件として直接使用できますが、グループ化の計算関数をフィルター条件として使用することはできません。HAVING は GROUP BY と組み合わせて使用​​する必要があり、グループ計算関数とグループ フィールドはフィルター条件として使用できます。これにより、データをグループ化してカウントする必要がある場合に、WHERE では完了できないタスクを HAVING で完了できることが決まります。これは、クエリ構文構造で WHERE が GROUP BY の前にあるため、グループ化された結果をフィルター処理できないためです。HAVING GROUP BY の後、グループ化フィールドとグループ化内の計算関数を使用して、グループ化された結果セットをフィルタリングできます。これは WHERE では実行できません。また、WHERE によって除外されたレコードはグループ化に含まれなくなります。
  • 違い 2: 接続を通じて関連テーブルから必要なデータを取得する必要がある場合、WHERE は最初にフィルタリングしてから接続しますが、HAVING は最初に接続してからフィルタリングします。この点により、関連するクエリでは WHERE が HAVING よりも効率的であることが決まります。これは、WHERE を最初にフィルタリングすることができ、より小さいフィルタリングされたデータ セットを使用して関連テーブルに接続できるため、占有リソースが少なくなり、実行効率が高くなります。HAVING では、最初に結果セットを準備する必要があります。つまり、フィルタリングされていないデータ セットに関連付けてから、大きなデータ セットをフィルタリングする必要があります。これにより、より多くのリソースが消費され、実行効率が低下します。

開発時の選択肢: WHERE と HAVING は相互排他的ではなく、1 つのクエリで WHERE と HAVING の両方を使用できます。HAVING はグループ化統計関数などの条件に使用され、WHERE は一般的な条件に使用されます。このようにして、WHERE 条件の高い効率と速度を活用するだけでなく、HAVING がグループ統計関数を含むクエリ条件を使用できるという利点も活用します。特にデータ量が多い場合には、作業効率が大きく異なります。

おすすめ

転載: blog.csdn.net/qq_39756007/article/details/127214436