線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:1745
推到 Plurk!
推到 Facebook!

SQL 中 like 及 select 的組合

答題得分者是:azurecloud
P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-11-13 23:52:57 IP:61.71.xxx.xxx 未訂閱
請問各位! 我現在有一個需求 有兩個欄位 PARTCODE, PARTNO, 現需使用PARTNO做 LIKE 比對, 先查出 LIKE 比對下如果只有一筆, 則取出 PARTCODE 值再對同一TABLE 做WHERE抓取資料, 如果比對出來不只一筆, 則以一個 DBGRID 顯示所有LIKE出來的記錄 我希望做到如下(我使用InterBase FB1.5版) (IB下這個語法是不接受的) query1.sql.text:= 'select PARTCODE, count(*) from xxxx where PARTNO like :iPARTNO' .... if query1.fieldbyname('count').value = 1 then begin mycode:= query1.fieldbyname('PARTCODE').value; query2.sql.text:= 'select * from xxx where partcode= :iPARTCODE'; ... 丟值.... end else if query1.fieldbyname('count').value > 1 then begin ... query2.sql.text:= 'select * from xxx where partcode= :iPARTCODE'; 開啟dbgrid end .... 也就是在同一個query上就可以得知partcode值及count數 但因為sql 不支援 select fieldname, count()的寫法, 所以我必須用三個 query來解決 query1:= 'select count(*) from xxx where PARTNO like :iPARTNO' query2:= 'select PARTCODE from xxx where PARTNO like :iPARTNO' query3:= 'select * from ...where partcode= :iPARTCODE'; 先以query1來決定筆數 如果有記錄, 則以query2取得 partcode 值(每一筆partno記錄的partcode值是相同) 取得partcode值再由query3抓取真正的 query欄位 有沒有辦法再簡化, 以上都只有對上同一個table, 謝謝! 發表人 - P.D. 於 2003/11/13 23:59:02
timhuang
尊榮會員


發表:78
回覆:1815
積分:1608
註冊:2002-07-15

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-11-14 01:11:02 IP:61.62.xxx.xxx 未訂閱
那就直接下:    select * from xxx where PARTNO like :iPARTNO    再以 Query1.RecordCount 來取得筆數. 不論是一筆或多筆, 你需要的資料不就都取出來了嗎 @@"    
if Query1.RecordCount = 1 then
  getdata from Query1
else if Query1.RecordCount > 1 then
  set dbgrid to datasource assigned to Query1
else
  no data!! (RecordCount = 0)
  
另: sql 並不是不支援 select fieldname, count() 的寫法, 而是使用了集總函數(Aggregate function, like count, sum, avg, max, min)後, 其餘欄位必須放置放 Group by 子句之後, 否則如何集總(統計)呢? 不過仔細想一下. 你的需求的第一點還是有問題的, 因為是 partno like 後, 僅一筆, 還要再 switch 條件改為 partcode = 該單一筆的 partcode, 的確是一道 query 達不到的. 因為用了兩種條件, 所以結論應該還是起碼要兩道, 修正 suedo code 如下:
if Query1.RecordCount = 1 then
  getdata from Query1
  select * from xxx where partcode = Query1.fieldbyname('partcode')
else if Query1.RecordCount > 1 then
  set dbgrid to datasource assigned to Query1
else
  no data!! (RecordCount = 0)
  
問題點在於第一道 query 後, 若結果為 1 筆, 要改變查詢條件的問題!!
azurecloud
中階會員


發表:52
回覆:108
積分:92
註冊:2003-09-04

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-11-14 01:13:20 IP:163.13.xxx.xxx 未訂閱
Hi, P.D. 您好: 請參考以下語法,這個語法不計算 count(*),而是有符合的 PARTNO 資料 存在時,再選出所有的 PARTCODE 所在的資料。記得 else 一定要加,我測試 過在 SQL Server 2000 時此語法可以 work 但當 if exists (select PARTNO from xxx where PARTNO like :iPARTNO) 無資料時會出現錯誤訊息,補一個「沒有符合的資料」就不會出錯了,希望對 你有幫助。 if exists (select PARTNO from xxx where PARTNO like :iPARTNO) begin select * from xxx where partcode in (select PARTCODE from xxx where PARTNO like :iPARTNO group by PARTCODE) end else select '沒有符合的資料' as nodata
P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-11-14 22:21:50 IP:61.71.xxx.xxx 未訂閱
那就直接下:    select * from xxx where PARTNO like :iPARTNO    再以 Query1.RecordCount 來取得筆數. 不論是一筆或多筆, 你需要的資料不就都取出來了嗎 @@"     query 並不支援recordcount用法, 你可以實際用一個dbgrid 來測試 舉例, 一個table有100筆, 用 select count(*) 可以得到100筆, 但在 dbgrid下, 如果dbgrid 在畫面上可顯示15筆, 則 recordcount 是15筆! 不過仔細想一下. 你的需求的第一點還是有問題的, 因為是 partno like 後, 僅一筆, 還要再 switch 條件改為 partcode = 該單一筆的 partcode, 的確是一道 query 達不到的. 因為用了兩種條件, 所以結論應該還是起碼要兩道, 修正 suedo code 如下:
if Query1.RecordCount = 1 then
  getdata from Query1
  select * from xxx where partcode = Query1.fieldbyname('partcode')
else if Query1.RecordCount > 1 then
  set dbgrid to datasource assigned to Query1
else
  no data!! (RecordCount = 0)
  
如果recordcount 無法達成, 那上述的行為是否仍是兩個query就可以做到嗎? 謝謝!
P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#5 引用回覆 回覆 發表時間:2003-11-14 22:29:13 IP:61.71.xxx.xxx 未訂閱
引言: Hi, P.D. 您好: 請參考以下語法,這個語法不計算 count(*),而是有符合的 PARTNO 資料 存在時,再選出所有的 PARTCODE 所在的資料。記得 else 一定要加,我測試 過在 SQL Server 2000 時此語法可以 work 但當 if exists (select PARTNO from xxx where PARTNO like :iPARTNO) 無資料時會出現錯誤訊息,補一個「沒有符合的資料」就不會出錯了,希望對 你有幫助。 if exists (select PARTNO from xxx where PARTNO like :iPARTNO) begin select * from xxx where partcode in (select PARTCODE from xxx where PARTNO like :iPARTNO group by PARTCODE) end else select '沒有符合的資料' as nodata
1.我使用的是INTERBASE, IB好像無法接受上述的寫法 2.我一定要知道 like 結果的 record數, 因為程式中必須判斷1筆或多筆時 其內的程式段有其必要性的工作要執行, 所以我想 第一個query一定少不了用 count()來取出數量, 但因為用count無法取得一 個partcode序號(如果可以的話, 那就可以同時作業, 不用像我現在必須用 三道query), 所以我想是否能用更少的query來完成, 畢竟query越少效能應 該會較好!
azurecloud
中階會員


發表:52
回覆:108
積分:92
註冊:2003-09-04

發送簡訊給我
#6 引用回覆 回覆 發表時間:2003-11-14 23:55:38 IP:163.13.xxx.xxx 未訂閱
Hi, P.D. 您好:    抱歉小弟才疏學淺,沒學過 INTERBASE,我有去查過 ANSI SQL 92 X3H2-92-154/DBL CBR-002 8.8  Function Specify a test for a non-empty set. Format ::= EXISTS Syntax Rules None. Access Rules None. General Rules 1) Let T be the result of the
. 2) If the cardinality of T is greater than 0, then the result of the is true; otherwise, the result of the is false. Leveling Rules 1) The following restrictions apply for Intermediate SQL: None. 2) The following restrictions apply for Entry SQL in addition to any Intermediate SQL restrictions: None. 222 Database Language SQL 我也查過 INTERBASE 相容於 ANSI SQL 92 ,這一段 SQL 應該可執行才是 還有 P.D. 大大,我實際測試 Query1.recordcount 可以抓得到耶(我的 資料筆數是 5574 應該已經超過 DBGrid 所能顯示的了)那如果可以用的 話(還是說您不要去設定 DBGrid 的顯示筆數?),您只要加個判斷: if query1.recordcount = 1 then if DBGrid1.Fields[0].value = '沒有符合的資料' then 做沒有資料時的動作 else 做有一筆資料時的動作 else 做有多筆資料時的動作 以上給您參考。
azurecloud
中階會員


發表:52
回覆:108
積分:92
註冊:2003-09-04

發送簡訊給我
#7 引用回覆 回覆 發表時間:2003-11-15 00:02:32 IP:163.13.xxx.xxx 未訂閱
抱歉,剛剛節錄的那一段漏一句 8.8  Function Specify a test for a non-empty set. Format "exists predicate" ::= EXISTS "table subquery" // 被系統當成 Html 語法了 Syntax Rules None. Access Rules None. General Rules 1) Let T be the result of the . 2) If the cardinality of T is greater than 0, then the result of the is true; otherwise, the result of the is false. Leveling Rules 1) The following restrictions apply for Intermediate SQL: None. 2) The following restrictions apply for Entry SQL in addition to any Intermediate SQL restrictions: None. 222 Database Language SQL
P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#8 引用回覆 回覆 發表時間:2003-11-19 12:09:49 IP:61.71.xxx.xxx 未訂閱
感謝各位的協助, 不過我在Interbase中暫時無法試出各位所提出的解決方法 因案子纏身, 一個月要趕3個案子, 目前只好先以我的方式作業, 等明年有空 再來研究!
系統時間:2024-05-17 12:21:02
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!