最優(yōu)良人 » mysql http://www.dgkai.cn/blog 中山php|最優(yōu)網(wǎng)絡(luò) Mon, 13 May 2013 04:56:43 +0000 en hourly 1 http://wordpress.org/?v=3.1.4 mysql STRICT_TRANS_TABLES嚴(yán)格模式下提示Field 'id' doesn't have a default value http://www.dgkai.cn/blog/view-411.html http://www.dgkai.cn/blog/view-411.html#comments Wed, 26 Sep 2012 03:42:48 +0000 lin http://www.dgkai.cn/blog/?p=411 在別的服務(wù)器運(yùn)行我的網(wǎng)站程序的時(shí)候,出現(xiàn)了Field 'id' doesn't have a default value 的提示,意思是這個(gè)值我沒(méi)有提交數(shù)據(jù),并且數(shù)據(jù)庫(kù)結(jié)構(gòu)沒(méi)有設(shè)置默認(rèn)值,由于對(duì)方的mysql服務(wù)器開(kāi)啟了STRICT_TRANS_TABLES嚴(yán)格模式,所以報(bào)錯(cuò)了

解決方法是:

如果自己的服務(wù)器,有權(quán)限修改my.ini的話,打開(kāi)my.ini,查找
sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

修改為

sql-mode="NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

然后重啟MYSQL

在別人的虛擬空間上當(dāng)然不可能實(shí)現(xiàn),所以根本的解決方法還是修改自己的數(shù)據(jù)結(jié)構(gòu),把非空的字段加上默認(rèn)值,以后設(shè)計(jì)數(shù)據(jù)庫(kù)要注意這一點(diǎn),方便程序的移植

]]>
http://www.dgkai.cn/blog/view-411.html/feed 431
mysql所有數(shù)據(jù)庫(kù)引擎用法MyISAM、InnoDB、MERGE、MEMORY(HEAP)、BDB(BerkeleyDB)、EXAMPLE、FEDERATED、ARCHIVE、CSV、BLACKHOLE http://www.dgkai.cn/blog/view-277.html http://www.dgkai.cn/blog/view-277.html#comments Wed, 21 Sep 2011 06:50:37 +0000 lin http://www.dgkai.cn/blog/?p=277 MySQL有多種存儲(chǔ)引擎,每種存儲(chǔ)引擎有各自的優(yōu)缺點(diǎn),大家可以擇優(yōu)選擇使用:

MyISAM、InnoDB、MERGE、MEMORY(HEAP)、BDB(BerkeleyDB)、EXAMPLE、FEDERATED、ARCHIVE、CSV、BLACKHOLE。

MySQL支持?jǐn)?shù)個(gè)存儲(chǔ)引擎作為對(duì)不同表的類型的處理器。MySQL存儲(chǔ)引擎包括處理事務(wù)安全表的引擎和處理非事務(wù)安全表的引擎:

· MyISAM管理非事務(wù)表。它提供高速存儲(chǔ)和檢索,以及全文搜索能力。MyISAM在所有MySQL配置里被支持,它是默認(rèn)的存儲(chǔ)引擎,除非你配置MySQL默認(rèn)使用另外一個(gè)引擎。

· MEMORY存儲(chǔ)引擎提供“內(nèi)存中”表。MERGE存儲(chǔ)引擎允許集合將被處理同樣的MyISAM表作為一個(gè)單獨(dú)的表。就像MyISAM一樣,MEMORY和MERGE存儲(chǔ)引擎處理非事務(wù)表,這兩個(gè)引擎也都被默認(rèn)包含在MySQL中。

注釋:MEMORY存儲(chǔ)引擎正式地被確定為HEAP引擎。

· InnoDB和BDB存儲(chǔ)引擎提供事務(wù)安全表。BDB被包含在為支持它的操作系統(tǒng)發(fā)布的MySQL-Max二進(jìn)制分發(fā)版里。InnoDB也默認(rèn)被包括在所 有MySQL 5.1二進(jìn)制分發(fā)版里,你可以按照喜好通過(guò)配置MySQL來(lái)允許或禁止任一引擎。
· EXAMPLE存儲(chǔ)引擎是一個(gè)“存根”引擎,它不做什么。你可以用這個(gè)引擎創(chuàng)建表,但沒(méi)有數(shù)據(jù)被存儲(chǔ)于其中或從其中檢索。這個(gè)引擎的目的是服務(wù),在 MySQL源代碼中的一個(gè)例子,它演示說(shuō)明如何開(kāi)始編寫新存儲(chǔ)引擎。同樣,它的主要興趣是對(duì)開(kāi)發(fā)者。

· NDB Cluster是被MySQL Cluster用來(lái)實(shí)現(xiàn)分割到多臺(tái)計(jì)算機(jī)上的表的存儲(chǔ)引擎。它在MySQL-Max 5.1二進(jìn)制分發(fā)版里提供。這個(gè)存儲(chǔ)引擎當(dāng)前只被Linux, Solaris, 和Mac OS X 支持。在未來(lái)的MySQL分發(fā)版中,我們想要添加其它平臺(tái)對(duì)這個(gè)引擎的支持,包括Windows。

· ARCHIVE存儲(chǔ)引擎被用來(lái)無(wú)索引地,非常小地覆蓋存儲(chǔ)的大量數(shù)據(jù)。

· CSV存儲(chǔ)引擎把數(shù)據(jù)以逗號(hào)分隔的格式存儲(chǔ)在文本文件中。

· BLACKHOLE存儲(chǔ)引擎接受但不存儲(chǔ)數(shù)據(jù),并且檢索總是返回一個(gè)空集。

· FEDERATED存儲(chǔ)引擎把數(shù)據(jù)存在遠(yuǎn)程數(shù)據(jù)庫(kù)中。在MySQL 5.1中,它只和MySQL一起工作,使用MySQL C Client API。在未來(lái)的分發(fā)版中,我們想要讓它使用其它驅(qū)動(dòng)器或客戶端連接方法連接到另外的數(shù)據(jù)源。

當(dāng)你創(chuàng)建一個(gè)新表的時(shí)候,你可以通過(guò)添加一個(gè)ENGINE 或TYPE 選項(xiàng)到CREATE TABLE語(yǔ)句來(lái)告訴MySQL你要?jiǎng)?chuàng)建什么類型的表:

CREATE TABLE t (i INT) ENGINE = INNODB;

CREATE TABLE t (i INT) TYPE = MEMORY;

雖然TYPE仍然在MySQL 5.1中被支持,現(xiàn)在ENGINE是首選的術(shù)語(yǔ)。

如何選擇最適合你的存儲(chǔ)引擎呢?

下述存儲(chǔ)引擎是最常用的:

· MyISAM:默認(rèn)的MySQL插件式存儲(chǔ)引擎,它是在Web、數(shù)據(jù)倉(cāng)儲(chǔ)和其他應(yīng)用環(huán)境下最常使用的存儲(chǔ)引擎之一。注意,通過(guò)更改STORAGE_ENGINE配置變量,能夠方便地更改MySQL服務(wù)器的默認(rèn)存儲(chǔ)引擎。

· InnoDB:用于事務(wù)處理應(yīng)用程序,具有眾多特性,包括ACID事務(wù)支持。

· BDB:可替代InnoDB的事務(wù)引擎,支持COMMIT、ROLLBACK和其他事務(wù)特性。

· Memory:將所有數(shù)據(jù)保存在RAM中,在需要快速查找引用和其他類似數(shù)據(jù)的環(huán)境下,可提供極快的訪問(wèn)。

· Merge:允許MySQL DBA或開(kāi)發(fā)人員將一系列等同的MyISAM表以邏輯方式組合在一起,并作為1個(gè)對(duì)象引用它們。對(duì)于諸如數(shù)據(jù)倉(cāng)儲(chǔ)等VLDB環(huán)境十分適合。

· Archive:為大量很少引用的歷史、歸檔、或安全審計(jì)信息的存儲(chǔ)和檢索提供了完美的解決方案。

· Federated:能夠?qū)⒍鄠€(gè)分離的MySQL服務(wù)器鏈接起來(lái),從多個(gè)物理服務(wù)器創(chuàng)建一個(gè)邏輯數(shù)據(jù)庫(kù)。十分適合于分布式環(huán)境或數(shù)據(jù)集市環(huán)境。

· Cluster/NDB:MySQL的簇式數(shù)據(jù)庫(kù)引擎,尤其適合于具有高性能查找要求的應(yīng)用程序,這類查找需求還要求具有最高的正常工作時(shí)間和可用性。

· Other:其他存儲(chǔ)引擎包括CSV(引用由逗號(hào)隔開(kāi)的用作數(shù)據(jù)庫(kù)表的文件),Blackhole(用于臨時(shí)禁止對(duì)數(shù)據(jù)庫(kù)的應(yīng)用程序輸入),以及Example引擎(可為快速創(chuàng)建定制的插件式存儲(chǔ)引擎提供幫助)。

記住,對(duì)于整個(gè)服務(wù)器或方案,你并不一定要使用相同的存儲(chǔ)引擎,你可以為方案中的每個(gè)表使用不同的存儲(chǔ)引擎,這點(diǎn)很重要。

mysql> show engines;
+——————–+————+———————————————–———————-—————————–+
| Engine | Support | Comment |
+——————–+————+———————————————————–———————-——————+
| MyISAM | DEFAULT | Default engine as of MySQL 3.23 with great performance |
| MEMORY | YES | Hash based, stored in memory, useful for temporary tables |
| InnoDB | YES | Supports transactions, row-level locking, and foreign keys |
| BerkeleyDB | NO | Supports transactions and page-level locking |
| BLACKHOLE | NO | /dev/null storage engine (anything you write to it disappears) |
| EXAMPLE | NO | Example storage engine |
| ARCHIVE | NO | Archive storage engine |
| CSV | NO | CSV storage engine |
| ndbcluster | NO | Clustered, fault-tolerant, memory-based tables |
| FEDERATED | NO | Federated MySQL storage engine |
| MRG_MYISAM | YES | Collection of identical MyISAM tables |
| ISAM | NO | Obsolete storage engine |
+————+———+—————————————————————————————-+

]]>
http://www.dgkai.cn/blog/view-277.html/feed 94
mysql數(shù)據(jù)庫(kù)引擎HEAP(MEMORY)的使用,內(nèi)存表,臨時(shí)表的用法 http://www.dgkai.cn/blog/view-275.html http://www.dgkai.cn/blog/view-275.html#comments Wed, 21 Sep 2011 06:47:44 +0000 lin http://www.dgkai.cn/blog/?p=275 HEAP表是訪問(wèn)數(shù)據(jù)速度最快的MySQL表,他使用保存在內(nèi)存中的散列索引。但如果MySQL或者服務(wù)器重新啟動(dòng),表中數(shù)據(jù)將會(huì)丟失.
用法:如論壇的在線人數(shù)統(tǒng)計(jì),這種表的數(shù)據(jù)應(yīng)該是無(wú)關(guān)緊要的,就幾個(gè)簡(jiǎn)單的字段,數(shù)據(jù)也不多,記錄數(shù)怎么也不會(huì)超過(guò)1000吧,但是操作是最頻繁的(基本用戶的每次動(dòng)作都要更新這個(gè)表).

如何創(chuàng)建內(nèi)存表?
創(chuàng)建內(nèi)存表非常的簡(jiǎn)單,只需注明 ENGINE= MEMORY 即可:
CREATE TABLE `tablename` ( `columnName` varchar(256) NOT NUL) ENGINE=MEMORY DEFAULT CHARSET=latin1 MAX_ROWS=100000000;

注意:
當(dāng)內(nèi)存表中的數(shù)據(jù)大于max_heap_table_size設(shè)定的容量大小時(shí),mysql會(huì)轉(zhuǎn)換超出的數(shù)據(jù)存儲(chǔ)到磁盤上,因此這是性能就大打折扣了,所 以我們還需要根據(jù)我們的實(shí)際情況調(diào)整max_heap_table_size,例如在.cnf文件中[mysqld]的下面加入:
max_heap_table_size = 2048M
另外在建表語(yǔ)句中還可以通過(guò)MAX_ROWS來(lái)控制表的記錄數(shù)。

內(nèi)存表使用哈希散列索引把數(shù)據(jù)保存在內(nèi)存中,因此具有極快的速度,適合緩存中小型數(shù)據(jù)庫(kù),但是使用上受到一些限制。

1、heap對(duì)所有用戶的連接是可見(jiàn)的,這使得它非常適合做緩存。

2、僅適合使用的場(chǎng)合。heap不允許使用xxxTEXT和xxxBLOB數(shù)據(jù)類型;只允許使用=和<=>操作符來(lái)搜索記錄 (不允許<、>、<=或>=);不支持auto_increment;只允許對(duì)非空數(shù)據(jù)列進(jìn)行 索引(not null)。
注:操作符 “<=>” 說(shuō)明:NULL-safe equal.這個(gè)操作符和“=”操作符執(zhí)行相同的比較操作,不過(guò)在兩個(gè)操作碼均為NULL時(shí),其所得值為1而不為NULL,而當(dāng)一個(gè)操作碼為NULL時(shí),其所得值為0而不為NULL。

3、一旦服務(wù)器重啟,所有heap表數(shù)據(jù)丟失,但是heap表結(jié)構(gòu)仍然存在,因?yàn)閔eap表結(jié)構(gòu)是存放在實(shí)際數(shù)據(jù)庫(kù)路徑下的,不會(huì)自動(dòng)刪除。重啟之后,heap將被清空,這時(shí)候?qū)eap的查詢結(jié)果都是空的。

4、如果heap是復(fù)制的某數(shù)據(jù)表,則復(fù)制之后所有主鍵、索引、自增等格式將不復(fù)存在,需要重新添加主鍵和索引,如果需要的話。

5、對(duì)于重啟造成的數(shù)據(jù)丟失,有以下的解決辦法:
a、在任何查詢之前,執(zhí)行一次簡(jiǎn)單的查詢,判斷heap表是否存在數(shù)據(jù),如果不存在,則把數(shù)據(jù)重新寫入,或者DROP表重新復(fù)制某張表。這需要多做一次查詢。不過(guò)可以寫成include文件,在需要用該heap表的頁(yè)面隨時(shí)調(diào)用,比較方便。
b、對(duì)于需要該heap表的頁(yè)面,在該頁(yè)面第一次且僅在第一次查詢?cè)摫頃r(shí),對(duì)數(shù)據(jù)集結(jié)果進(jìn)行判斷,如果結(jié)果為空,則需要重新寫入數(shù)據(jù)。這樣可以節(jié)省一次查詢。
c、更好的辦法是在mysql每次重新啟動(dòng)時(shí)自動(dòng)寫入數(shù)據(jù)到heap,但是需要配置服務(wù)器,過(guò)程比較復(fù)雜,通用性受到限制。

6、一些預(yù)期可能用到的sql語(yǔ)句

//如果表存在,則刪除
DROP TABLE IF EXISTS `abc`;
//復(fù)制整張表xyz為heap表abc(包含所有數(shù)據(jù))
CREATE TABLE `abc` type=heap select * from `xyz`;
//添加主鍵id
ALTER TABLE `abc` ADD PRIMARY KEY (`id`);
//添加索引username
ALTER TABLE `abc` ADD INDEX `abc` (`username`);

其它參考:
官方文檔:As indicated by the name, MEMORY tables are stored in memory. They use hash indexes by default, which makes them very fast, and very useful for creating temporary tables. However, when the server shuts down, all rows stored in MEMORY tables are lost. The tables themselves continue to exist because their definitions are stored in .frm files on disk, but they are empty when the server restarts.

可以看出來(lái)MEMORY確實(shí)是very fast,and very useful for creating temporary tables .把臨時(shí)表和內(nèi)存表放在一起使用確實(shí)會(huì)快不少:create table tmp2(id int not null) engine memory;
內(nèi)存表的建立還有一些限制條件:
MEMORY tables cannot contain BLOB or TEXT columns. HEAP不支持BLOB/TEXT列。
The server needs sufficient memory to maintain all MEMORY tables that are in use at the same time. 在同一時(shí)間需要足夠的內(nèi)存.
To free memory used by a MEMORY table when you no longer require its contents, you should execute DELETE or TRUNCATE TABLE, or remove the table altogether using DROP TABLE.為了釋放內(nèi)存,你應(yīng)該執(zhí)行DELETE FROM heap_table或DROP TABLE heap_table。

幾個(gè)關(guān)鍵參數(shù)

max_heap_table_size
mysql HEAP MEMORY tables 提高行數(shù)支持的方法
別人問(wèn)到的 記一下
mysql MEMORY tables 如果目前支持的行數(shù)到上限還不夠用 可以把 my.conf 配置里面
max_heap_table_size = 256M
改大
設(shè)置 MAX_ROWS
在跑著 可以 ALTER TABLE tbl_name MAX_ROWS=
MAX_ROWS 依賴于 max_heap_table_size 設(shè)置

]]>
http://www.dgkai.cn/blog/view-275.html/feed 407
mysql字符串替換函數(shù)replace http://www.dgkai.cn/blog/view-230.html http://www.dgkai.cn/blog/view-230.html#comments Sat, 27 Aug 2011 15:07:47 +0000 lin http://www.dgkai.cn/blog/?p=230 mysql替換字符串函數(shù)replace可以實(shí)現(xiàn)把某字段的某些字符串替換成其他字符串,例如

update dede_addonarticle set body=replace(body,'news/uploads/allimg/c110826','news/uploads/blank.gif?')

可以把dedecms的文章內(nèi)容表所有的圖片鏈接替換成空白圖片,這樣就可以去把已經(jīng)上傳的大量圖片刪除以節(jié)省空間了,在對(duì)采集回來(lái)的數(shù)據(jù)尤其有用。

]]>
http://www.dgkai.cn/blog/view-230.html/feed 323
phpmyadmin 默認(rèn)數(shù)據(jù)庫(kù)引擎修改為myisam http://www.dgkai.cn/blog/view-181.html http://www.dgkai.cn/blog/view-181.html#comments Thu, 25 Aug 2011 04:24:42 +0000 lin http://www.dgkai.cn/blog/?p=181
phpmyadmin 默認(rèn)創(chuàng)建的數(shù)據(jù)庫(kù)默認(rèn)的數(shù)據(jù)庫(kù)引擎為innodb,如果希望修改為靈活性更高的myisam
在my.ini找到default-storage-engine=innodb,修改為myisam
]]>
http://www.dgkai.cn/blog/view-181.html/feed 356
Mysql查詢數(shù)據(jù)表中某字段重復(fù)出現(xiàn)的次數(shù),并按照次數(shù)排序 http://www.dgkai.cn/blog/view-90.html http://www.dgkai.cn/blog/view-90.html#comments Sat, 13 Aug 2011 18:29:55 +0000 lin http://www.dgkai.cn/blog/?p=90

利用Mysql中的 的聚合函數(shù) count(*) 可以實(shí)現(xiàn)這個(gè)功能,例如需要查詢data表中name出現(xiàn)次數(shù)最多的記錄,可以先按照group by name分組,用count算出分組里的條數(shù),再按照count排序:

select name,count(*) from data group by name order by count(*) DESC limit 1

不加limit限制將返回按照name重復(fù)次數(shù)排列的數(shù)據(jù)

]]>
http://www.dgkai.cn/blog/view-90.html/feed 419
Mysql Having的用法:對(duì)group by之后的分組加限制條件 http://www.dgkai.cn/blog/view-88.html http://www.dgkai.cn/blog/view-88.html#comments Sat, 13 Aug 2011 18:27:50 +0000 lin http://www.dgkai.cn/blog/?p=88

在使用聚合函數(shù)之前,我們可以通過(guò)where對(duì)查詢加限制條件,那么如果在group by之后我們要對(duì)分組里面的數(shù)據(jù)再加限制條件怎么辦呢?答案是having。

HAVING子句可以讓我們篩選成組后的各組數(shù)據(jù).
WHERE子句在聚合前先篩選記錄.也就是說(shuō)作用在GROUP BY 子句和HAVING子句前.
而 HAVING子句在聚合后對(duì)組記錄進(jìn)行篩選。

having子句出現(xiàn)的數(shù)據(jù)必須在group by 之后,order by 之后

例如在上一篇中對(duì)name按照出現(xiàn)次數(shù)排序之后,我們還想只查出名字里面含有l(wèi)in的數(shù)據(jù),可以這樣寫:

select name ,count(*) from data group by name having name like '%lin%' order by couny(*) DESC

]]>
http://www.dgkai.cn/blog/view-88.html/feed 683
Mysql 子查詢的用法 http://www.dgkai.cn/blog/view-69.html http://www.dgkai.cn/blog/view-69.html#comments Sat, 13 Aug 2011 17:00:34 +0000 lin http://www.dgkai.cn/blog/?p=69 一,子選擇基本用法
1,子選擇的定義
子迭擇允許把一個(gè)查詢嵌套在另一個(gè)查詢當(dāng)中。比如說(shuō):一個(gè)考試記分項(xiàng)目把考試事件分為考試(T)和測(cè)驗(yàn)(Q)兩種情形。下面這個(gè)查詢就能只找出學(xué)生們的考試成績(jī)
select * from score where event_id in (select event_id from event where type='T');
2,子選擇的用法(3種)
? 用子選擇來(lái)生成一個(gè)參考值
在這種情況下,用內(nèi)層的查詢語(yǔ)句來(lái)檢索出一個(gè)數(shù)據(jù)值,然后把這個(gè)數(shù)據(jù)值用在外層查詢語(yǔ)句的比較操作中。比如說(shuō),如果要查詢表中學(xué)生們?cè)谀骋惶斓臏y(cè)驗(yàn)成績(jī),就應(yīng)該使用一個(gè)內(nèi)層查詢先找到這一天的測(cè)驗(yàn)的事件號(hào),然后在外層查詢語(yǔ)句中用這個(gè)事件號(hào)在成績(jī)表里面找到學(xué)生們的分?jǐn)?shù)記錄。具體語(yǔ)句為:
select * from score where
id=(select event_id from event where date='2002-03-21' and type='Q');
需要注意的是:在應(yīng)用這種內(nèi)層查詢的結(jié)果主要是用來(lái)進(jìn)行比較操作的分法時(shí),內(nèi)層查詢應(yīng)該只有一個(gè)輸出結(jié)果才對(duì)。看例子,如果想知道哪個(gè)美國(guó)總統(tǒng)的生日最小,構(gòu)造下列查詢
select * from president where birth=min(birth)
這個(gè)查詢是錯(cuò)的!因?yàn)镸ySQL不允許在子句里面使用統(tǒng)計(jì)函數(shù)!min()函數(shù)應(yīng)該有一個(gè)確定的參數(shù)才能工作!所以我們改用子選擇:
select * from president where birht=(select min(birth) from presidnet);
? exists 和 not exists 子選擇
上一種用法是把查間結(jié)果由內(nèi)層傳向外層、本類用法則相反,把外層查詢的結(jié)果傳遞給內(nèi)層??赐獠坎樵兊慕Y(jié)果是否滿足內(nèi)部查間的匹配徑件。這種"由外到內(nèi)"的子迭擇用法非常適合用來(lái)檢索某個(gè)數(shù)據(jù)表在另外一個(gè)數(shù)據(jù)表里面有設(shè)有匹配的記錄

數(shù)據(jù)表t1 數(shù)據(jù)表t2
I1 C1 I2 C2
1
2
3 A

C 2
3
4 C

A
先找兩個(gè)表內(nèi)都存在的數(shù)據(jù)
select i1 from t1 where exists(select * from t2 where t1.i1=t2.i2);
再找t1表內(nèi)存在,t2表內(nèi)不存在的數(shù)據(jù)
select i1 form t1 where not exists(select * from t2 where t1.i1=t2.i2);

需要注意:在這兩種形式的子選擇里,內(nèi)層查詢中的星號(hào)代表的是外層查詢的輸出結(jié)果。內(nèi)層查詢沒(méi)有必要列出有關(guān)數(shù)據(jù)列的名字,田為內(nèi)層查詢關(guān)心的是外層查詢的結(jié)果有多少行。希望大家能夠理解這一點(diǎn)
? in 和not in 子選擇
在這種子選擇里面,內(nèi)層查詢語(yǔ)句應(yīng)該僅僅返回一個(gè)數(shù)據(jù)列,這個(gè)數(shù)據(jù)列里的值將由外層查詢語(yǔ)句中的比較操作來(lái)進(jìn)行求值。還是以上題為例
先找兩個(gè)表內(nèi)都存在的數(shù)據(jù)
select i1 from t1 where i1 in (select i2 from t2);
再找t1表內(nèi)存在,t2表內(nèi)不存在的數(shù)據(jù)
select i1 form t1 where i1 not in (select i2 from t2);
好象這種語(yǔ)句更容易讓人理解,再來(lái)個(gè)例子
比如你想找到所有居住在A和B的學(xué)生。
select * from student where state in('A','B')
二, 把子選擇查詢改寫為關(guān)聯(lián)查詢的方法。
1,匹配型子選擇查詢的改寫
下例從score數(shù)據(jù)表里面把學(xué)生們?cè)诳荚囀录═)中的成績(jī)(不包括測(cè)驗(yàn)成績(jī)?。┎樵兂鰜?lái)。
Select * from score where event_id in (select event_id from event where type='T');
可見(jiàn),內(nèi)層查詢找出所有的考試事件,外層查詢?cè)倮眠@些考試事件搞到學(xué)生們的成績(jī)。
這個(gè)子查詢可以被改寫為一個(gè)簡(jiǎn)單的關(guān)聯(lián)查詢:
Select score.* from score, event where score.event_id=event.event_id and event.event_id='T';
下例可以用來(lái)找出所有女學(xué)生的成績(jī)。
Select * from score where student_id in (select student_id form student where sex = 'f');
可以把它轉(zhuǎn)換成一個(gè)如下所示的關(guān)聯(lián)查詢:
Select * from score
Where student _id =student.student_id and student.sex ='f';
把匹配型子選擇查詢改寫為一個(gè)關(guān)聯(lián)查詢是有規(guī)律可循的。下面這種形式的子選擇查詢:
Select * from tablel
Where column1 in (select column2a from table2 where column2b = value);
可以轉(zhuǎn)換為一個(gè)如下所示的關(guān)聯(lián)查詢:
Select tablel. * from tablel,table2
Where table.column1 = table2.column2a and table2.column2b = value;
(2)非匹配(即缺失)型子選擇查詢的改寫
子選擇查詢的另一種常見(jiàn)用途是查找在某個(gè)數(shù)據(jù)表里有、但在另一個(gè)數(shù)據(jù)表里卻沒(méi)有的東西。正如前面看到的那樣,這種"在某個(gè)數(shù)據(jù)表里有、在另一個(gè)數(shù)據(jù)表里沒(méi)有"的說(shuō)法通常都暗示著可以用一個(gè)left join 來(lái)解決這個(gè)問(wèn)題。請(qǐng)看下面這個(gè)子選擇查詢,它可以把沒(méi)有出現(xiàn)在absence數(shù)據(jù)表里的學(xué)生(也就是那些從未缺過(guò)勤的學(xué)生)給查出來(lái):
Select * from student
Where student_id not in (select student_id from absence);
這個(gè)子選擇查詢可以改寫如下所示的left join 查詢:
Select student. *
From student left join absence on student.student_id =absence.student_id
Where absence.student_id is null;
把非匹配型子選擇查詢改寫為關(guān)聯(lián)查詢是有規(guī)律可循的。下面這種形式的子選擇查詢:
Select * from tablel
Where column1 not in (select column2 from table2);
可以轉(zhuǎn)換為一個(gè)如下所示的關(guān)聯(lián)查詢:
Select tablel . *
From tablel left join table2 on tablel.column1=table2.column2
Where table2.column2 is null;
注意:這種改寫要求數(shù)據(jù)列table2.column2聲明為not null。

]]>
http://www.dgkai.cn/blog/view-69.html/feed 337
mysql操作符in between http://www.dgkai.cn/blog/view-65.html http://www.dgkai.cn/blog/view-65.html#comments Sat, 13 Aug 2011 16:57:30 +0000 lin http://www.dgkai.cn/blog/?p=65

以下三條sql語(yǔ)句的效果是等效的:

SELECT * FROM `logs` WHERE id = 1 or id = 2 or id = 3

SELECT * FROM `logs` WHERE id between 1 and 3

SELECT * FROM `logs` WHERE id in (1,2,3)

經(jīng)過(guò)測(cè)試性能也是差不多,如果id是一個(gè)大數(shù)組那么最后一條書寫會(huì)簡(jiǎn)單很多,可以利用php的

string implode ( string $glue , array $pieces )

函數(shù)把數(shù)組組合成(implode(',',$array))也就是(1,2,3)這樣的格式

]]>
http://www.dgkai.cn/blog/view-65.html/feed 331
常用的Mysql語(yǔ)句 http://www.dgkai.cn/blog/view-63.html http://www.dgkai.cn/blog/view-63.html#comments Sat, 13 Aug 2011 16:53:05 +0000 lin http://www.dgkai.cn/blog/?p=63

1 登陸mysql服務(wù)器

mysql -uroot -ppassword

2 進(jìn)入數(shù)據(jù)庫(kù)

use haxinbbs;

3 插入一條記錄

insert into user(username,password) values('harryzyp','harryzyp');

sql="insert into 目標(biāo)數(shù)據(jù)表 select * from 源數(shù)據(jù)表" (把源數(shù)據(jù)表的記錄添加到目標(biāo)數(shù)據(jù)表)

4 查看一個(gè)記錄或多個(gè)

select password,sex(或*) from user where username='harryzyp';(等于 = 不等于 <> 小于 < 大于 > 小于或等于 <= 大于或等于 >=)

sql="select * from 數(shù)據(jù)表 where 字段名 in ( 值1 , 值2 , 值3 )"
sql="select * from 數(shù)據(jù)表 where 字段名 between 值1 and 值2"

模糊查詢

SQL的模式匹配允許你使用"_"匹配任何單個(gè)字符,而"%"匹配任意數(shù)目字符(包括零個(gè)字符)。

為了找出包含一個(gè)"w"的名字:
mysql> SELECT * FROM pet WHERE name LIKE "%w%";

select * from qq where id like '%8%';

限制以Publishing結(jié)尾,使用LIKE '%Publishing'
限制以A開(kāi)頭:LIKE '[A]%'
限制以A開(kāi)頭外:LIKE '[^A]%'

-求工資最高的員工姓名

use pangu

select e_name

from employee

where e_wage =

(select max(e_wage)

from employee)

用戶可以使用邏輯連接符AND,OR和NOT。

SELECT * FROM EMPLOYEES
  WHERE LAST_NAME = 'Jones' AND FIRST_NAME = 'Davy';

SELECT * FROM EMPLOYEES
  WHERE LAST_NAME = 'Jones' OR LAST_NAME = 'Smith';

SELECT * FROM EMPLOYEES
  WHERE NOT(BRANCH_OFFICE = 'Boston');

SELECT * FROM EMPLOYEES
  WHERE (LAST_NAME = 'Jones'
  AND FIRST_NAME = 'Indiana')
  OR (LAST_NAME = 'Smith'
  AND FIRST_NAME = 'Bessie');

斷言中進(jìn)行NULL判斷

SELECT * FROM EMPLOYEES
  WHERE SALARY IS NULL;

SELECT * FROM EMPLOYEES
  WHERE SALARY IS NOT NULL;

要消除結(jié)果中的重復(fù)行,只要在SELECT語(yǔ)句中加上DISTINCT子句:

SELECT DISTINCT BRANCH_OFFICE FROM EMPLOYEES;

使用ORDER BY子句就可以按照升序或降序來(lái)排列結(jié)果:(如果你希望以降序排列,那么可以用關(guān)鍵字DESC)

  SELECT DISTINCT BRANCH_OFFICE

  FROM EMPLOYEES

ORDER BY BRANCH_OFFICE ASC;

按照字符串長(zhǎng)度排序

order by length($str) DESC

第一個(gè)技巧:利用連接符連接多個(gè)字段。

  如在員工基本信息表中,有員工姓名、員工職位、出身日期等等。如果現(xiàn)在視圖中這三個(gè)字段顯示在同一個(gè)字段中,并且中間有分割符。如我現(xiàn)在想顯示的結(jié)果為"經(jīng)理Victor出身于1976年5月3日"。這該如何處理呢?其實(shí),這是比較簡(jiǎn)單的,我們可以在Select查詢語(yǔ)句中,利用連接符把這些字段連接起來(lái)。

  如可以這么寫查詢語(yǔ)句:

  SELECT員工職位 ||' ' ||員工姓名||'出身于'||出身日期 as 員工出身信息 FROM 員工基本信息表;

  通過(guò)這條語(yǔ)句就可以實(shí)現(xiàn)如上的需求。也就是說(shuō),我們?cè)谄綍r(shí)查詢中,可以利用||連接符把一些相關(guān)的字段連接起來(lái)。這在報(bào)表視圖中非常的有用。如筆者以前在設(shè)計(jì)圖書館管理系統(tǒng)的時(shí)候,在書的基本信息處有圖書的出版社、出版序列號(hào)等等內(nèi)容。但是,有時(shí)會(huì)在打印報(bào)表的時(shí)候,需要把這些字段合并成一個(gè)字段打印。為此,就需要利用這個(gè)連接符把這些字段連接起來(lái)。而且,利用連接符還可以在字段中間加入一些說(shuō)明性的文字,以方便大家閱讀。如上面我在員工職位與員工姓名之間加入了空格;并且在員工姓名與出身日期之間加入了出身于幾個(gè)注釋性的文字。這些功能看起來(lái)比較小,但是卻可以大大的提高內(nèi)容的可讀性。這也是我們?cè)跀?shù)據(jù)庫(kù)設(shè)計(jì)過(guò)程中需要關(guān)注的一個(gè)內(nèi)容。

  總之,令后采用連接符,可以提高我們報(bào)表的可讀性于靈活性。

5 修改字段

update user set password='harryzyp' where username='xiaohe';

sql="update 數(shù)據(jù)表 set 字段1=值1,字段2=值2 …… 字段n=值n where 條件表達(dá)式"

6 刪除一個(gè)字段

delete from user where username='xiaohe';

7 創(chuàng)建一個(gè)表

create table books(id varchar(8) primary key,name varchar(24));

8 查看一個(gè)表中的所有字段名

desc person;

9 查看所有數(shù)據(jù)庫(kù)或表

show databases或show tables;

有兩個(gè)表student和elective,建立SQL腳本如下:

create table student(id int(10) not null primary key,name varchar(20) not null);

create table elective(id int(10) auto_increment primary key,stu_id int(10) not null,class_name varchar(20));

插入數(shù)據(jù)略!!

10 查詢第二個(gè)字符為"a"的學(xué)生(student)

select * from student where name like '_a%';

11 查詢已經(jīng)選過(guò)課的選課信息

select * from elective as e inner join student as s where e.stu_id=s.id;

附: (1)inner可省略 (2)where可用on代替

12 查詢所有學(xué)生的選課信息

select * from student as s left join elective as e on s.id=e.stu_id;

附: (1)on不能用where代替

13 同11

select * from student as s right join elective as e on s.id=e.stu_id;

14 字查詢舉例

select * from student s where 2<=(select count(*) from elective e where e.stu_id=s.id);

15 把某列的內(nèi)容復(fù)制到另外一列

update authors set au_lname= authors.job_desc

070917添加

1 MSSQL取出表中前10條數(shù)據(jù)

select top 10 * from tableName;

2 MSSQL取出表中前10%的數(shù)據(jù)

select top 10 percent * from tableName;

3 MySQL取出表中前10條數(shù)據(jù)

select * from tableName limit 10;

4MySQL取出表中4—9的數(shù)據(jù)

select * from tableName limit 3,6;

limit a,b a表示取a-1條,b表示取多少條

4查看當(dāng)天發(fā)布的帖子

select * from article where posttime like 'yyyy-MM-dd%'

5設(shè)置mysql默認(rèn)字符編碼命令

set names gbk;

6數(shù)據(jù)記錄統(tǒng)計(jì)函數(shù):
AVG(字段名) 得出一個(gè)表格欄平均值
COUNT(*|字段名) 對(duì)數(shù)據(jù)行數(shù)的統(tǒng)計(jì)或?qū)δ骋粰谟兄档臄?shù)據(jù)行數(shù)統(tǒng)計(jì)
MAX(字段名) 取得一個(gè)表格欄最大的值
MIN(字段名) 取得一個(gè)表格欄最小的值
SUM(字段名) 把數(shù)據(jù)欄的值相加
sql="select sum(字段名) as 別名 from 數(shù)據(jù)表 where 條件表達(dá)式"
set rs=conn.excute(sql)
用 rs("別名") 獲取統(tǒng)的計(jì)值,其它函數(shù)運(yùn)用同上。

文章出處:http://www.diybl.com/course/3_program/java/javajs/2007104/75907.html

模糊查詢

SQL的模式匹配允許你使用"_"匹配任何單個(gè)字符,而"%"匹配任意數(shù)目字符(包括零個(gè)字符)。

在 MySQL中,SQL的模式缺省是忽略大小寫的。下面顯示一些例子。注意在你使用SQL模式時(shí),你不

能使用=或!=;而使用LIKE或NOT LIKE比較操作符。

為了找出以"b"開(kāi)頭的名字:
mysql> SELECT * FROM pet WHERE name LIKE "b%";

為了找出以"fy"結(jié)尾的名字:
mysql> SELECT * FROM pet WHERE name LIKE "%fy";

為了找出包含一個(gè)"w"的名字:
mysql> SELECT * FROM pet WHERE name LIKE "%w%";

為了找出包含正好5個(gè)字符的名字,使用"_"模式字符:
mysql> SELECT * FROM pet WHERE name LIKE "_____";

由MySQL提供的模式匹配的其他類型是使用擴(kuò)展正則表達(dá)式。當(dāng)你對(duì)這類模式進(jìn)行匹配測(cè)試時(shí),使用

REGEXP和NOT REGEXP操作符(或RLIKE和NOT RLIKE,它們是同義詞)。

擴(kuò)展正則表達(dá)式的一些字符是:

"."匹配任何單個(gè)的字符。
一個(gè)字符類"[...]"匹配在方括號(hào)內(nèi)的任何字符。例如,"[abc]"匹配"a"、"b"或"c"。
為了命名字符的一個(gè)范圍,使用一個(gè)"-"。"[a-z]"匹配任何小寫字母,而"[0-9]"匹配任
何數(shù)字。
" * "匹配零個(gè)或多個(gè)在它前面的東西。例如,"x*"匹配任何數(shù)量的"x"字符,"[0-9]*"
匹配的任何數(shù)量的數(shù)字,而".*"匹配任何數(shù)量的任何東西。
正則表達(dá)式是區(qū)分大小寫的,但是如果你希望,你能使用一個(gè)字符類匹配兩種寫法。例如,
"[aA]"匹配小寫或大寫的"a"而"[a-zA-Z]"匹配兩種寫法的任何字母。
如果它出現(xiàn)在被測(cè)試值的任何地方,模式就匹配(只要他們匹配整個(gè)值,SQL模式匹配)。
為了定位一個(gè)模式以便它必須匹配被測(cè)試值的開(kāi)始或結(jié)尾,在模式開(kāi)始處使用"^"或在模式的
結(jié)尾用"$"。
為了說(shuō)明擴(kuò)展正則表達(dá)式如何工作,上面所示的LIKE查詢?cè)谙旅媸褂肦EGEXP重寫:

為了找出以"b"開(kāi)頭的名字,使用"^"匹配名字的開(kāi)始并且"[bB]"匹配小寫或大寫的"b":
mysql> SELECT * FROM pet WHERE name REGEXP "^[bB]";

為了找出以"fy"結(jié)尾的名字,使用"$"匹配名字的結(jié)尾:
mysql> SELECT * FROM pet WHERE name REGEXP "fy$";

為了找出包含一個(gè)"w"的名字,使用"[wW]"匹配小寫或大寫的"w":
mysql> SELECT * FROM pet WHERE name REGEXP "[wW]";

既然如果一個(gè)正規(guī)表達(dá)式出現(xiàn)在值的任何地方,其模式匹配了,就不必再先前的查詢中在模式的兩
方面放置一個(gè)通配符以使得它匹配整個(gè)值,就像如果你使用了一個(gè)SQL模式那樣。
為了找出包含正好5個(gè)字符的名字,使用"^"和"$"匹配名字的開(kāi)始和結(jié)尾,和5個(gè)"."實(shí)例在
兩者之間:
mysql> SELECT * FROM pet WHERE name REGEXP "^.....$";

你也可以使用"{n}""重復(fù)n次"操作符重寫先前的查詢:
mysql> SELECT * FROM pet WHERE name REGEXP "^.{5}$";

查找數(shù)字和其他的模糊查詢語(yǔ)句
Select * from pet where name REGEXP "[^a-zA-Z].";

簡(jiǎn)單的Transact-SQL查詢只包括選擇列表、FROM子句和WHERE子句
一、 簡(jiǎn)單查詢
簡(jiǎn)單的Transact-SQL查詢只包括選擇列表、FROM子句和WHERE子句。它們分別說(shuō)明所查詢列、查詢的表或視圖、以及搜索條件等。
例如,下面的語(yǔ)句查詢testtable表中姓名為"張三"的nickname字段和email字段。

SELECT nickname,emailFROM testtable

WHERE name='張三'

(一) 選擇列表
選擇列表(select_list)指出所查詢列,它可以是一組列名列表、星號(hào)、表達(dá)式、變量(包括局部變量和全局變量)等構(gòu)成。
1、選擇所有列
例如,下面語(yǔ)句顯示testtable表中所有列的數(shù)據(jù):

SELECT *FROM testtable

2、選擇部分列并指定它們的顯示次序
查詢結(jié)果集合中數(shù)據(jù)的排列順序與選擇列表中所指定的列名排列順序相同。
例如:

SELECT nickname,emailFROM testtable

3、更改列標(biāo)題
在選擇列表中,可重新指定列標(biāo)題。定義格式為:
列標(biāo)題=列名
列名 列標(biāo)題
如果指定的列標(biāo)題不是標(biāo)準(zhǔn)的標(biāo)識(shí)符格式時(shí),應(yīng)使用引號(hào)定界符,例如,下列語(yǔ)句使用漢字顯示列標(biāo)題:

SELECT 昵稱=nickname,電子郵件=emailFROM testtable

4、刪除重復(fù)行
SELECT語(yǔ)句中使用ALL或DISTINCT選項(xiàng)來(lái)顯示表中符合條件的所有行或刪除其中重復(fù)的數(shù)據(jù)行,默認(rèn)為ALL。使用DISTINCT選項(xiàng)時(shí),對(duì)于所有重復(fù)的數(shù)據(jù)行在SELECT返回的結(jié)果集合中只保留一行。
5、限制返回的行數(shù)
使用TOP n [PERCENT]選項(xiàng)限制返回的數(shù)據(jù)行數(shù),TOP n說(shuō)明返回n行,而TOP n PERCENT時(shí),說(shuō)明n是表示一百分?jǐn)?shù),指定返回的行數(shù)等于總行數(shù)的百分之幾。
例如:

SELECT TOP 2 *FROM testtable SELECT TOP 20 PERCENT * FROM testtable

(二)FROM子句FROM子句指定SELECT語(yǔ)句查詢及與查詢相關(guān)的表或視圖。在FROM子句中最多可指定256個(gè)表或視圖,它們之間用逗號(hào)分隔。
在FROM子句同時(shí)指定多個(gè)表或視圖時(shí),如果選擇列表中存在同名列,這時(shí)應(yīng)使用對(duì)象名限定這些列所屬的表或視圖。例如在usertable和citytable表中同時(shí)存在cityid列,在查詢兩個(gè)表中的cityid時(shí)應(yīng)使用下面語(yǔ)句格式加以限定:

SELECT username,citytable.cityidFROM usertable,citytable

WHERE usertable.cityid=citytable.cityid

在FROM子句中可用以下兩種格式為表或視圖指定別名:
表名 as 別名
表名 別名
例如上面語(yǔ)句可用表的別名格式表示為:

SELECT username,b.cityidFROM usertable a,citytable b

WHERE a.cityid=b.cityid

SELECT不僅能從表或視圖中檢索數(shù)據(jù),它還能夠從其它查詢語(yǔ)句所返回的結(jié)果集合中查詢數(shù)據(jù)。
例如:

SELECT a.au_fname+a.au_lnameFROM authors a,titleauthor ta

(SELECT title_id,title

FROM titles

WHERE ytd_sales>10000

) AS t

WHERE a.au_id=ta.au_id

AND ta.title_id=t.title_id

此例中,將SELECT返回的結(jié)果集合給予一別名t,然后再?gòu)闹袡z索數(shù)據(jù)。
(三) 使用WHERE子句設(shè)置查詢條件
WHERE子句設(shè)置查詢條件,過(guò)濾掉不需要的數(shù)據(jù)行。例如下面語(yǔ)句查詢年齡大于20的數(shù)據(jù):

SELECT *FROM usertable

WHERE age>20

WHERE子句可包括各種條件運(yùn)算符:
比較運(yùn)算符(大小比較):>、>=、=、<、<=、<>、!>、!<
范圍運(yùn)算符(表達(dá)式值是否在指定的范圍):BETWEEN…AND…
NOT BETWEEN…AND…
列表運(yùn)算符(判斷表達(dá)式是否為列表中的指定項(xiàng)):IN (項(xiàng)1,項(xiàng)2……)
NOT IN (項(xiàng)1,項(xiàng)2……)
模式匹配符(判斷值是否與指定的字符通配格式相符):LIKE、NOT LIKE
空值判斷符(判斷表達(dá)式是否為空):IS NULL、NOT IS NULL
邏輯運(yùn)算符(用于多條件的邏輯連接):NOT、AND、OR
1、范圍運(yùn)算符例:age BETWEEN 10 AND 30相當(dāng)于age>=10 AND age<=30
2、列表運(yùn)算符例:country IN ('Germany','China')
3、模式匹配符例:常用于模糊查找,它判斷列值是否與指定的字符串格式相匹配??捎糜赾har、varchar、text、ntext、datetime和smalldatetime等類型查詢。
可使用以下通配字符:
百分號(hào)%:可匹配任意類型和長(zhǎng)度的字符,如果是中文,請(qǐng)使用兩個(gè)百分號(hào)即%%。
下劃線_:匹配單個(gè)任意字符,它常用來(lái)限制表達(dá)式的字符長(zhǎng)度。
方括號(hào)[]:指定一個(gè)字符、字符串或范圍,要求所匹配對(duì)象為它們中的任一個(gè)。[^]:其取值也[] 相同,但它要求所匹配對(duì)象為指定字符以外的任一個(gè)字符。
例如:
限制以Publishing結(jié)尾,使用LIKE '%Publishing'
限制以A開(kāi)頭:LIKE '[A]%'
限制以A開(kāi)頭外:LIKE '[^A]%'
4、空值判斷符例WHERE age IS NULL
5、邏輯運(yùn)算符:優(yōu)先級(jí)為NOT、AND、OR
(四)查詢結(jié)果排序
使用ORDER BY子句對(duì)查詢返回的結(jié)果按一列或多列排序。ORDER BY子句的語(yǔ)法格式為:
ORDER BY {column_name [ASC|DESC]} [,…n]
其中ASC表示升序,為默認(rèn)值,DESC為降序。ORDER BY不能按ntext、text和image數(shù)據(jù)類型進(jìn)行排序。
例如:

SELECT *FROM usertable

ORDER BY age desc,userid ASC

另外,可以根據(jù)表達(dá)式進(jìn)行排序。
二、 聯(lián)合查詢
UNION運(yùn)算符可以將兩個(gè)或兩個(gè)以上上SELECT語(yǔ)句的查詢結(jié)果集合合并成一個(gè)結(jié)果集合顯示,即執(zhí)行聯(lián)合查詢。UNION的語(yǔ)法格式為:

select_statementUNION [ALL] selectstatement

[UNION [ALL] selectstatement][…n]

其中selectstatement為待聯(lián)合的SELECT查詢語(yǔ)句。
ALL選項(xiàng)表示將所有行合并到結(jié)果集合中。不指定該項(xiàng)時(shí),被聯(lián)合查詢結(jié)果集合中的重復(fù)行將只保留一行。
聯(lián)合查詢時(shí),查詢結(jié)果的列標(biāo)題為第一個(gè)查詢語(yǔ)句的列標(biāo)題。因此,要定義列標(biāo)題必須在第一個(gè)查詢語(yǔ)句中定義。要對(duì)聯(lián)合查詢結(jié)果排序時(shí),也必須使用第一查詢語(yǔ)句中的列名、列標(biāo)題或者列序號(hào)。
在使用UNION 運(yùn)算符時(shí),應(yīng)保證每個(gè)聯(lián)合查詢語(yǔ)句的選擇列表中有相同數(shù)量的表達(dá)式,并且每個(gè)查詢選擇表達(dá)式應(yīng)具有相同的數(shù)據(jù)類型,或是可以自動(dòng)將它們轉(zhuǎn)換為相同的數(shù)據(jù)類型。在自動(dòng)轉(zhuǎn)換時(shí),對(duì)于數(shù)值類型,系統(tǒng)將低精度的數(shù)據(jù)類型轉(zhuǎn)換為高精度的數(shù)據(jù)類型。
在包括多個(gè)查詢的UNION語(yǔ)句中,其執(zhí)行順序是自左至右,使用括號(hào)可以改變這一執(zhí)行順序。例如:
查詢1 UNION (查詢2 UNION 查詢3)
三、連接查詢
通過(guò)連接運(yùn)算符可以實(shí)現(xiàn)多個(gè)表查詢。連接是關(guān)系數(shù)據(jù)庫(kù)模型的主要特點(diǎn),也是它區(qū)別于其它類型數(shù)據(jù)庫(kù)管理系統(tǒng)的一個(gè)標(biāo)志。
在關(guān)系數(shù)據(jù)庫(kù)管理系統(tǒng)中,表建立時(shí)各數(shù)據(jù)之間的關(guān)系不必確定,常把一個(gè)實(shí)體的所有信息存放在一個(gè)表中。當(dāng)檢索數(shù)據(jù)時(shí),通過(guò)連接操作查詢出存放在多個(gè)表中的不同實(shí)體的信息。連接操作給用戶帶來(lái)很大的靈活性,他們可以在任何時(shí)候增加新的數(shù)據(jù)類型。為不同實(shí)體創(chuàng)建新的表,爾后通過(guò)連接進(jìn)行查詢。
連接可以在SELECT 語(yǔ)句的FROM子句或WHERE子句中建立,似是而非在FROM子句中指出連接時(shí)有助于將連接操作與WHERE子句中的搜索條件區(qū)分開(kāi)來(lái)。所以,在Transact-SQL中推薦使用這種方法。
SQL-92標(biāo)準(zhǔn)所定義的FROM子句的連接語(yǔ)法格式為:

FROM join_table join_type join_table[ON (join_condition)]

其中join_table指出參與連接操作的表名,連接可以對(duì)同一個(gè)表操作,也可以對(duì)多表操作,對(duì)同一個(gè)表操作的連接又稱做自連接。
join_type 指出連接類型,可分為三種:內(nèi)連接、外連接和交叉連接。內(nèi)連接(INNER JOIN)使用比較運(yùn)算符進(jìn)行表間某(些)列數(shù)據(jù)的比較操作,并列出這些表中與連接條件相匹配的數(shù)據(jù)行。根據(jù)所使用的比較方式不同,內(nèi)連接又分為等值連接、自然連接和不等連接三種。外連接分為左外連接(LEFT OUTER JOIN或LEFT JOIN)、右外連接(RIGHT OUTER JOIN或RIGHT JOIN)和全外連接(FULL OUTER JOIN或FULL JOIN)三種。與內(nèi)連接不同的是,外連接不只列出與連接條件相匹配的行,而是列出左表(左外連接時(shí))、右表(右外連接時(shí))或兩個(gè)表(全外連接時(shí))中所有符合搜索條件的數(shù)據(jù)行。
交叉連接(CROSS JOIN)沒(méi)有WHERE 子句,它返回連接表中所有數(shù)據(jù)行的笛卡爾積,其結(jié)果集合中的數(shù)據(jù)行數(shù)等于第一個(gè)表中符合查詢條件的數(shù)據(jù)行數(shù)乘以第二個(gè)表中符合查詢條件的數(shù)據(jù)行數(shù)。
連接操作中的ON (join_condition) 子句指出連接條件,它由被連接表中的列和比較運(yùn)算符、邏輯運(yùn)算符等構(gòu)成。
無(wú)論哪種連接都不能對(duì)text、ntext和image數(shù)據(jù)類型列進(jìn)行直接連接,但可以對(duì)這三種列進(jìn)行間接連接。例如:

SELECT p1.pub_id,p2.pub_id,p1.pr_infoFROM pub_info AS p1 INNER JOIN pub_info AS p2

ON DATALENGTH(p1.pr_info)=DATALENGTH(p2.pr_info)

(一)內(nèi)連接內(nèi)連接查詢操作列出與連接條件匹配的數(shù)據(jù)行,它使用比較運(yùn)算符比較被連接列的列值。內(nèi)連接分三種:
1、等值連接:在連接條件中使用等于號(hào)(=)運(yùn)算符比較被連接列的列值,其查詢結(jié)果中列出被連接表中的所有列,包括其中的重復(fù)列。
2、不等連接: 在連接條件使用除等于運(yùn)算符以外的其它比較運(yùn)算符比較被連接的列的列值。這些運(yùn)算符包括>、>=、<=、<、!>、!<和<>。
3、自然連接:在連接條件中使用等于(=)運(yùn)算符比較被連接列的列值,但它使用選擇列表指出查詢結(jié)果集合中所包括的列,并刪除連接表中的重復(fù)列。
例,下面使用等值連接列出authors和publishers表中位于同一城市的作者和出版社:

SELECT *FROM authors AS a INNER JOIN publishers AS p

ON a.city=p.city

又如使用自然連接,在選擇列表中刪除authors 和publishers 表中重復(fù)列(city和state):

SELECT a.*,p.pub_id,p.pub_name,p.countryFROM authors AS a INNER JOIN publishers AS p

ON a.city=p.city

(二)外連接
內(nèi)連接時(shí),返回查詢結(jié)果集合中的僅是符合查詢條件( WHERE 搜索條件或 HAVING 條件)和連接條件的行。而采用外連接時(shí),它返回到查詢結(jié)果集合中的不僅包含符合連接條件的行,而且還包括左表(左外連接時(shí))、右表(右外連接時(shí))或兩個(gè)邊接表(全外連接)中的所有數(shù)據(jù)行。如下面使用左外連接將論壇內(nèi)容和作者信息連接起來(lái):

SELECT a.*,b.* FROM luntan LEFT JOIN usertable as bON a.username=b.username

下面使用全外連接將city表中的所有作者以及user表中的所有作者,以及他們所在的城市:

SELECT a.*,b.*FROM city as a FULL OUTER JOIN user as b

ON a.username=b.username

(三)交叉連接
交叉連接不帶WHERE 子句,它返回被連接的兩個(gè)表所有數(shù)據(jù)行的笛卡爾積,返回到結(jié)果集合中的數(shù)據(jù)行數(shù)等于第一個(gè)表中符合查詢條件的數(shù)據(jù)行數(shù)乘以第二個(gè)表中符合查詢條件的數(shù)據(jù)行數(shù)。例,titles表中有6類圖書,而publishers表中有8家出版社,則下列交叉連接檢索到的記錄數(shù)將等
于6*8=48行。 SELECT type,pub_name

FROM titles CROSS JOIN publishers

ORDER BY type

[Post=0][/Post]

]]>
http://www.dgkai.cn/blog/view-63.html/feed 492