⑴ 在sql-SERVER2000中對同一個資料庫多張表進行查詢時怎樣避免笛卡兒乘積
在寫join類型的語句的時候,最好使用join來代替直接用「,」分隔多個表。這樣必須提供on條件才能進行查詢。當然,join的條件一定要設置好,否則也會出現笛卡爾積的。
比如tableA和TableB向關聯的是ID欄位
如果用「,「分隔兩個表的話語據應該如下
select count(*)
from tableA ,TableB
where TableA.id=TableB.id
如果把where 語句漏掉就出現笛卡爾積了
select count(*)
from tableA ,TableB
同樣,寫成join的話,如果不指定on里的條件的話,語法是錯的
select count(*)
from TableA join TableB
on TableA.id=TableB.id
但是如果再on里指定了一個錯誤的關聯條件的話,也是會出現笛卡爾積的,比如:
select count(*)
from TableA join TableB
on 1=1
當然一般人不會閑得去把on條件設置成1=1,不過這是舉個例子,就是為了說明on的篩選條件一定要設置好。
⑵ SQL sum函數一對多場景,消除笛卡爾積
貸款表
還款表
其中還款表使用load_id作為外鍵與貸款表關聯。
貸款表數據
還款表數據
結果為 110.00
結果為 65.00
結果為 270.00
關聯情況下,貸款表查詢出的實際數據如下,可以看出這種情況下出現了笛卡爾積。
load_id為5的貸款對應3條還款,load_id為8的貸款對應2條還款。所以sum(lc.load_amt)的結果270 = 50 * 3 + 60*2。
解決方案,使用 DISTINCT 關鍵字。
結果 110.00
結果為 270.00 , 65.00。
跟場景三一樣,貸款金額出現了笛卡爾積
這種情況可以分兩步走
這種方式可能不是很好理解,換成子查詢方式。
結果
結果
⑶ sql join on 多個表 怎麼防止卡迪爾乘積
join 肯定就是笛卡爾積,所以你on 後面跟的條件就非常關鍵,如果沒有on連接條件,就是完全的笛卡爾積,100條學生數據和100條成績數據笛卡爾積就是10000條數據。
所以兩個表join,需要按on後面的條件去連接就沒啥事了,100條學生數據和100條成績數據,on 學生表.學號=成績表.學號,按這個條件join,就只會去連接滿足連接條件的值
⑷ 寫sql語句 一般什麼時候出現笛卡爾積如何避免
樓主這個問題,表達的不是很准確。事實上你所說的什麼時候出現笛卡爾積,應該是指一對多關系的時候,如果避免重復,而不是如何避免笛卡爾積。笛卡爾積在SQL中是有特殊的關聯來求笛卡爾積的,求笛卡爾積的指令是crossjoin。那麼回到如何避免重復的問題上,一般對於SQL開發來說,這是讓很多人頭疼的問題。一般呢,我個人把重復定義為如下三種情況:x0dx0a第一種,原數據重復,指的是對應關系表中的數據本身就存在重復。但這種情況並不多,開發的時候會設定主鍵,一般情況較少。這種情況通常把需要使用的粒度數據distinct後,再關聯就可以了。x0dx0a第二種,就是維度重復。比如有區域表,分別是省市縣三列,而你要統計的是到省的數據,這樣你直接寫join的時液茄候會直接關聯出很多條,這樣通常鬧皮察使用子查詢去除維度重復後,再關聯即可x0dx0a第三種,就是在一對多關系關聯出來後的數據維度重復。有些東西是存放很多關系表握輪的,在關系表關聯後出現重復數據是個很正常的事情,但是可能由於需求比較特別,這樣我們通常對這些數據進行排序組合,匯總後取數的原則,來選出我們需要的數據。x0dx0a當然,說了這么多,其實怎麼寫一段SQL,還是要看需求和數據結構。具體的數據結構和具體的需求,定位了一段SQL該怎麼寫。多實踐,你就會感悟到了
⑸ 為什麼在實際中要避免構造廣義笛卡爾積的SQL語句
兩個表相連,每個表10000條數據。如果不加連接條件,就會造成廣義笛卡兒積10000*10000=1億條數據,這樣的數據量你的計算機就受不了。所以在兩個表連接時一定要加鏈接條件,並且要想好邏輯
⑹ 為什麼在實際中要避免構造廣義笛卡爾積的sql語句
兩個表相連,每個表10000條數據。如果不加連接條件,就會手枝造成廣義笛喊讓卡兒積10000*10000=1億條數據,這樣的數據量你的計算機就受不了。所鄭薯局以在兩個表連接時一定要加鏈接條件,並且要想好邏輯
⑺ 什麼就是為查詢數據而定製的准則
這個書上應該都有的啊1.需求分析階段
准確了解與分析用戶需求(包括數據與版處理)
是整個設計過程的基礎,權是最困難、最耗費時間的一步
2.概念結構設計階段
是整個資料庫設計的關鍵
通過對用戶需求進行綜合、歸納與抽象,形成一個獨立於具體DBMS的概念模型
3.邏輯結構設計階段
將概念結構轉換為某個DBMS所支持的數據模型
對其進行優化
4.資料庫物理設計階段
為邏輯數據模型選取一個最適合應用環境的物理結構(包括存儲結構和存取方法)
5.資料庫實施階段
運用DBMS提供的數據語言、工具及宿主語言,根據邏輯設計和物理設計的結果
建立弊鉛資料庫,編制與調試應用程序,組織數據入庫,帶卜世並進行試運行
6.資料庫運行和維護階段
資料庫應用系統經過試運行後即可投入正式運行。
查詢檢索的優化首先想到你檢索條件中的欄位是不是索引欄位,不是的話版,建立索引
然後是權sql語句的優化,select其實就是循環,循環的次數越多,檢索效率越慢,子查詢可以有,但是不要超過三層,超過三層,估計就是檢索sql有問題,要重新梳理邏輯
避免笛卡爾積,幾個表關聯的時候,要用主鍵或者邏輯主鍵去關聯
聚蠢肢合函數的用法,要注意重復數據的過濾
where條件盡量寫詳細,條件越多,就能過濾掉更多的數據,這樣就會提高效率
對於百萬級別或者千萬級別的數據量的檢索,就不是sql優化那麼簡單了,要用到資料庫本身的一些優化機制,有些資料庫帶有臨時表,這是很好的優化方法
存儲過程也是可以優化sql的,一些循環或者條件判斷都可以用存儲過程來實現
⑻ sql關聯出現笛卡爾積現象怎樣避免
d與s沒有產生關聯,按照道理d與s會產生笛卡爾積但是你的查詢結果並沒有,這是因為完全用where條件來限制除了本身在實現你這個sql的時候,sql引擎有很多演算法1種是產生3個表的笛卡爾積,按照where來過濾。產生結果2、按照e和d來連接,產生結果,在於s來3、按照d和s產生笛卡爾積,在按照e和s來過濾等等本身你看到的只是一個運算結果。運算過程你並沒有看到,也就是sql引擎實際選擇使用哪種方法。所以不是說它沒有產生笛卡爾積,而是說它有可能產生,也有可能沒有產生,根據它的演算法自己決定。如果你想看到它到底有沒有選擇笛卡爾積的演算法,那麼就看看這個sql的實際執行計劃就知道了。
⑼ SQL實戰新手入門:交叉聯接(CROSS JOIN)
交叉聯接(CROSS JOIN)
最後 將介紹另外一種不同類型的聯接 實際上 它的語法不允許定義行匹配的條件
SELECT
loc_bookcase
loc_shelf
loc_position_left
bk_title
FROM location CROSS JOIN books
( row(s) affected)
這怎麼可能呢?查詢結果產生了 行記錄?在每一個表中僅有 條記錄啊!這是什麼類型的聯接呢?它就是交叉聯接 又稱為笛卡爾積 請回顧一下笛卡爾坐標系統 它由兩根互為直角的軸構成 兩軸交叉點的坐標為 並從 開始沿軸逐漸增加數值 笛卡爾坐標系統的一個常見的例子就是國際象棋的棋盤 它沿著軸用字母取代了數字 除此之外 兩者是類似的
如果對棋盤上陪冊的每一個方格進行命名 可以使用棋盤上的坐標 A A E E 等 換句話說 即將一個軸上的每一個值都與另外一個軸上的每一個值進行匹配 這就是笛卡爾積(這非常類似於將軸上的值 相乘 :A× A× 等)
CROSS JOIN對於兩個表執行類似的操作 它將一個表中的每一行與另外一個表中的每一行進行配對 可以想像 CROSS JOIN的結果集通常都源攜相當大 在上面的例子中 僅僅交叉聯接兩個表(每個表只有 行數據)就返回了 行結果 如果在查詢中加入更多的表 那麼結果集將蘆裂宏變得更加龐大
如何建立CROSS JOIN呢?實際上無需太多的語法 使用舊式SQL語法來創建CROSS JOIN非常簡單 只需要在FROM子句中列出要選取的表 無需任何JOIN條件
SELECT
loc_bookcase
loc_shelf
loc_position_left
bk_title
FROM location books
也就是說 無須使用任何JOIN關鍵字 只需要在FROM子句中列出要交叉聯接的表即可 但是這會產生一個困境 忽略WHERE子句將創建一個笛卡爾積的查詢 並且編寫這樣的SQL查詢非常簡單 然而 結果集可能會超出希望查詢的數據范圍 表 顯示了將LIBRARY資料庫中的表逐步增加到CROSS JOIN查詢中時結果集數量的增長過程
表 LIBRARY資料庫中的笛卡爾積
LIBRARY資料庫非常小 只包含 個表 其中沒有一個表超過 條記錄 但使用CROSSJOIN時卻產生了極大的結果集 設想一下 如果對於一個包含了幾十個甚至上百個表的產品級的資料庫(其中可能包含了上百萬的記錄)使用CROSS JOIN將會產生什麼樣的後果?毫無疑問 這會將資料庫折磨到掛掉 並讓DBA惱火不已
可以在CROSS JOIN中使用一個WHERE子句來減少返回記錄的數量 例如 使用下面的查詢產生一個笛卡爾積
SELECT loc_bookcase loc_shelf loc_position_left bk_title
FROM location CROSS JOIN books
WHERE bk_id =
該查詢僅返回 條記錄 而不是前面例子中的 條記錄
幸運的是 新的SQL語法要求首先顯式地聲明聯接的類型 這可以避免查詢意外地產生不必要的笛卡爾積 新SQL語法要求必須使用CROSS JOIN關鍵字或者應用聯接條件 對於DBA請注意以下的警告 使用舊的聯接語法對資料庫是有害的 很多RDBMS在它們各自的資料庫中已經停止了對舊語法的支持 除非需要處理遺留的代碼 否則在查詢中最好不要再使用舊式語法
讀者可能會感到疑惑 如果CROSS JOIN是不良的 應該避免使用的聯接 那為什麼還要自尋煩惱地提供CROSS JOIN關鍵字呢?實際上 CROSS JOIN也有合理的用途 例如 它提供了一個快速又簡單的辦法來產生巨量的數據集 可用於測試用途 另外一種應用場景是通過CROSS JOIN產生的數據集來選取行 這些行既無法通過INNER JOIN也無法通過OUTER JOIN來產生 例如 選取對於指定產品的銷售總量為 的客戶(或者在LIBRARY資料庫的情形下查詢在一年內沒有借閱一本特定圖書的客戶)
CROSS JOIN是一個極為強大的工具 因此也必須謹慎地加以使用 處理巨大的數據集將消耗系統資源 在SQL中 最佳實踐之一就是在查詢中盡可能地對記錄進行篩選 並最小化須訪問的數據的數量
一個SQL查詢對於可以包含多少個JOIN操作是否存在限制呢?對於預備執行計劃的復雜性都存在實際的限制 更不用說執行這些復雜的計劃可能會使伺服器崩潰 實際的數量取決於RDBMS以及運行RDBMS的硬體環境 如果你發現聯接太多的表 那麼應該重新考慮你的查詢方案
返回目錄 SQL實戰新手入門
編輯推薦
Oracle索引技術
高性能MySQL
lishixin/Article/program/SQL/201311/16467
⑽ SQL語句查詢出現笛卡爾怎麼辦
兩表連接如果要避免返回笛卡爾積,必須確保至少一方表是唯一的,否則在能查到記錄的情況下,不論哪一種連接方式一定會返回笛卡爾積記錄集的。
我們可以利用主鍵、唯一索引、distinct關鍵字和分組等手段來確保連接是一對多或一對一的,這樣就可以防止笛卡爾積發生。具體的實現方法要根據數據結構和查詢要求才能給出,可以說是千變萬化的,需要具體問題具體分析解決。