急...關於撈mysql資料的解決方法

edited 十月 2013 in PHP新手區
資料表內每一條資料都有一欄是在記錄自己是在那個群族之下的
所以我用以下方式表示
假設a資料是屬於1和8的群組
那記錄的方式就像是這樣
1,8,
若是3和6和8的群族,就會像
3,6,8,
就是數字後會接一個逗點

如果我想撈屬於8這個群組的資料
那我sql就會下
select * from tablename where like c_id '%8,%'

於是裡面有8的資料就會出來了

但後來發現到一個嚴重的問題><
如果有資料的欄是記錄18怎麼辦,例如
1,4,18,
那使用
select * from tablename where like c_id '%8,%'
也會連帶把這個資料也po出來

我有想過一個方法,那就是把資料結構改變,但這樣一來很多都要改到

所以想請問各位大大,有沒有不更改資料結構下的sql語法

感恩

原始討論: http://twpug.net/x/modules/newbb/viewtopic.php?topic_id=2033

評論

  • edited 八月 2006
    有找到一個函式: FIND_IN_SET

    http://dev.mysql.com/doc/refman/5.1/en/string-functions.html

    但還是建議改資料結構比較實際 :)
  • edited 八月 2006
    提供你一個我看過也正在用的作法:

    1. 把原來存 1,8,18 的欄位長度加大。

    2. 然後原來的 1,8,18 改存成 0000000001,0000000008,0000000018 。

    3. SQL 語法的 LIKE 部份,原來用 $id 的地方改用 sprintf('%010d', $id) 來比對。

    當然以上的做法不是沒有缺點,但以你的狀況而言應該適用。至於已有的資料要怎麼轉,請自己想辦法。
  • edited 八月 2006
    換個方向思考
    單純撈8的族群可以看成兩種狀況8,.... 或...,8,....
    那改成
    c_id like '8,%' or c_id like '%,8,%'
    應該就會濾掉18 28這些了(至於執行速度....有得必有失)
    不過如果一次要能select多個族群
    那sql語法上要注意的可能會更多
  • edited 八月 2006
    感謝各位的建議,
    看來還是免不了要改變資料結構

    我打算只要在前面加個逗點即可
    例如3,8,18,
    改成,3,8,18,

    那sql在撈3的資料時改成
    select * from tablename where like '%,3,%'
    即可精準撈出
  • edited 八月 2006
    你不必修改數據,直接檢測 concat(',', c_id) like '%,3,%' 便可以了,除非你肯定修改了數據後不會對系統其他部分做成影響。(順便一提,你些的 SQL statement 似乎沒有一句是合法的)

    不過,我建議你還是花時間修改數據庫的結構(請問 database schema 是這樣譯嗎?)才是長遠的解決之道,否則將來你要替一項資料增加/刪除群組,或者群組的數量太多超過了群組欄位的長度的時候,還有很多很多情況,問題還是要面對。

    你的數據庫結構犯了「在 PHP 數據庫應用中五種常見的錯誤」中所說的第四個毛病,我認為與其花心思扭六任逃避問題,不如堂堂正正把問題解決掉,用短暫的痛苦來換取執行效率、可讀性、可維護性、可擴展性的大幅提高,絕對值得。

    從學術的角度看,你的資料結構從根本上違反了關聯式數據庫的設計原則,建議你參考一些有關關聯式數據庫的理論書籍充實一下,這方面 Jeffery Ullman 的 Principles of Database and Knowledge Base Systems 可說是殿堂級的經典名著,不過我不肯定是否有中文版,這本書給予你的不僅是知識,還提高你的境界。
Sign In or Register to comment.