2016-02-26 23 views
3

我有一個像我NF的數據表結構從JSON數據

id | party | rights | m_id 
---+---------+------------+--------- 
9 |abc  | 3,5,6  | ["12,","15,"6"] 
20 |xyz  | 5,2  | ["6,","2,"9","12"] 
21 |xyz 1 | 5,2  | ["6,","9,"12"] 

現在,我想讓我的表在這樣 搜索結果的權5數據庫(MySQL的)表[「12」, 「15,」 6 「] [」 6 「」 2, 「12」] [ 「6」, 「9」,12" ]

12 | ABC,XYZ,XYZ1 |

15 | abc |

6 | abc,xyz,xyz1 |

9 | xyz,xyz1 |

+0

「等等都屬於派對桌」 - 瘋狂猜測模式:有一個sql查詢涉及到哪裏?如果有問題,請將其添加到您的問題。如果沒有,請提供您在php腳本中可用的實際數據(結構)。 – VolkerK

+0

我已經打倒了表格的形象@VolkerK – piyuu

+0

仍然令人困惑。起初你寫「右5包含三個表演ID」,然後「例如:輸出權9:派對2,派對3」。請詳細說明。我可以進入瘋狂的猜測模式:您正在尋找所有在'shows_id'字段的'rights'和_9'列中都有'5'的行嗎?但是這會立即導致我提出一個[數據庫規範化](https://en.wikipedia.org/wiki/Database_normalization);-) – VolkerK

回答

2

讓我們從我相信你已經擁有的東西開始。這是一個sscce。如果您調整mysql憑據,它應該在您的系統上運行,只創建一個臨時MySQL表。它使用PDO訪問MySQL服務器。其API 實際使用並不重要(即只要其他的API是mysqli的,因爲mysql_ *函數are depreacted ;-))

<?php 
$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'localonly', 'localonly', array(
    PDO::ATTR_EMULATE_PREPARES=>false, 
    PDO::MYSQL_ATTR_DIRECT_QUERY=>false, 
    PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION 
)); 
setup($pdo); 

$statement = $pdo->prepare(' 
    SELECT 
     * 
    FROM 
     soFoo 
    WHERE 
     FIND_IN_SET(:right, rights) 
'); 

$statement->execute(array(':right'=>5)); 

/* in one way or another you have a loop where you fetch the records 
having '5' in the `rights` field 
*/ 
foreach($statement as $row) { 
    echo $row['party'], ' ', $row['show_ids'], "\r\n"; 
} 


function setup($pdo) { 
    $pdo->exec(' 
     CREATE TEMPORARY TABLE soFoo 
    (`id` int, `party` varchar(9), `exc` varchar(13), `rights` varchar(5), `show_ids` varchar(27)) 
    '); 
    $pdo->exec(<<< eos 
     INSERT INTO soFoo 
      (`id`, `party`, `exc`, `rights`, `show_ids`) 
     VALUES 
      (9, 'Percept', 'Non-Exclusive', '3,5,6', '["12,","15,"6"]'), 
      (20, 'Tata Sky', 'Non-Exclusive', '5,4,', '["6,","9,"11"]'), 
      (21, 'Tata Sky', 'Exclusive', '5,4', '["6,","13","15,"2","4","9"]'), 
      (22, 'Simbiotic', 'Exclusive', '6,2', '["12,","15,"1","6","7","8"]') 
eos 
    ); 
} 

此打印

Percept ["12,","15,"6"] 
Tata Sky ["6,","9,"11"] 
Tata Sky ["6,","13","15,"2","4","9"] 

是(因爲我理解這個問題),只要你已經有了。

現在讓我們decode the JSON array和檢查whether it contains元素9。如果它不從當前行添加inforamtion到一個數組稱爲$parties

$parties = array(); 
/* in one way or another you have a loop where you fetch the records 
having '5' in the `rights` field 
*/ 
foreach($statement as $row) { 
    $ids = json_decode($row['show_ids'], true); 
    if (in_array('9', $ids)) { 
     $parties[$row['id']] = $row['party']; 
    } 
} 
var_export($parties); 

打印

array (
    20 => 'Tata Sky', 
    21 => 'Tata Sky', 
) 

但是......但從這是次優的....關係數據庫點。
FIND_IN_SET子句妨礙MySQL有效地使用索引;您正在搜索(複合)數據之內的單個字段。數據庫服務器實現可以做些什麼來提高性能是令人驚訝的;但它有限制。
而且您還將可能不必要的數據從MySQL服務器傳輸到php實例(那些5rights但不是9show_ids中的記錄)。如果可能,應該避免這種情況。網絡/網絡堆棧速度快,可以進行優化,RAM很便宜......但同樣存在限制。

所以,我建議你一方面看Database normalization和/或另一方面看document-oriented databases

0

我要給下面一個例子,所以你可以在你的方式寫,

如果您有見下表

id | name  
1 | a,b,c  
2 | b 

和預期產出這樣

id | name  
1 | a  
1 | b  
1 | c  
2 | b 

然後請遵循以下解決方案

如果您可以創建一個數字表,其中包含數字M 1的最大領域拆分,可以使用這樣一個解決方案:

select 
    tablename.id, 
    SUBSTRING_INDEX(SUBSTRING_INDEX(tablename.name, ',', numbers.n), ',', -1) name 
from 
    numbers inner join tablename 
    on CHAR_LENGTH(tablename.name) 
    -CHAR_LENGTH(REPLACE(tablename.name, ',', ''))>=numbers.n-1 
order by 
    id, n 

請參閱小提琴here.

如果您不能創建一個表,然後一個解決方案可以是這樣:

select 
    tablename.id, 
    SUBSTRING_INDEX(SUBSTRING_INDEX(tablename.name, ',', numbers.n), ',', -1) name 
from 
    (select 1 n union all 
    select 2 union all select 3 union all 
    select 4 union all select 5) numbers INNER JOIN tablename 
    on CHAR_LENGTH(tablename.name) 
    -CHAR_LENGTH(REPLACE(tablename.name, ',', ''))>=numbers.n-1 
order by 
    id, n 

一個例子小提琴是here.