mysql select query within a serialized array

前端 未结 14 1230
忘了有多久
忘了有多久 2020-11-29 07:51

I\'m storing a list of items in a serialized array within a field in my database (I\'m using PHP/MySQL).

I want to have a query that will select all the records that

相关标签:
14条回答
  • 2020-11-29 08:06

    For easy method use :

    column_field_name LIKE %VALUE_TO_BE_SEARCHED_FOR%
    

    in MySQL query

    0 讨论(0)
  • 2020-11-29 08:06
    foreach( $result as $value ) {
       $hour = unserialize( $value->meta_value );
       if( $hour['date'] < $data['from'] ) {
         $sum = $sum + $hour['hours'];
       }
     }
    
    0 讨论(0)
  • 2020-11-29 08:08

    If you have control of the data model, stuffing serialized data in the database will bite you in the long run just about always. However, oftentimes one does not have control over the data model, for example when working with certain open source content management systems. Drupal sticks a lot of serialized data in dumpster columns in lieu of a proper model. For example, ubercart has a 'data' column for all of its orders. Contributed modules need to attach data to the main order entity, so out of convenience they tack it onto the serialized blob. As a third party to this, I still need a way to get at some of the data stuffed in there to answer some questions.

    a:4:{s:7:"cc_data";s:112:"6"CrIPY2IsMS1?blpMkwRj[XwCosb]gl<Dw_L(,Tq[xE)~(!$C"9Wn]bKYlAnS{[Kv[&Cq$xN-Jkr1qq<z](td]ve+{Xi!G0x:.O-"=yy*2KP0@z";s:7:"cc_txns";a:1:{s:10:"references";a:1:{i:0;a:2:{s:4:"card";s:4:"3092";s:7:"created";i:1296325512;}}}s:13:"recurring_fee";b:1;s:12:"old_order_id";s:2:"25";}
    

    see that 'old_order_id'? thats the key I need to find out where this recurring order came from, but since not everybody uses the recurring orders module, there isnt a proper place to store it in the database, so the module developer opted to stuff it in that dumpster table.

    My solution is to use a few targeted SUBSTRING_INDEX's to chisel off insignificant data until I've sculpted the resultant string into the data gemstone of my desires. Then I tack on a HAVING clause to find all that match, like so:

    SELECT uo.*,
    SUBSTRING_INDEX(
     SUBSTRING_INDEX(
      SUBSTRING_INDEX( uo.data, 'old_order_id' , -1 ),
     '";}', 1),
    '"',-1) 
    AS `old order id`
    FROM `uc_orders AS `uo`
    HAVING `old order id` = 25
    

    The innermost SUBSTRING_INDEX gives me everything past the old_order_id, and the outer two clean up the remainder.

    This complicated hackery is not something you want in code that runs more than once, more of a tool to get the data out of a table without having to resort to writing a php script.

    Note that this could be simplified to merely

    SELECT uo.*,
    SUBSTRING_INDEX(
      SUBSTRING_INDEX( uo.data, '";}' , 1 ),
    '"',-1) 
    AS `old order id`
    FROM `uc_orders` AS `uo`
    HAVING `old order id` = 25
    

    but that would only work in this specific case (the value I want is at the end of the data blob)

    0 讨论(0)
  • 2020-11-29 08:09

    How about you serialize the value you're searching for?

    $sql = sprintf("select * from tbl WHERE serialized_col like  '%%%s%%'", serialize($n));
    

    or

    $sql = sprintf("select * from tbl WHERE serialized_col like  '%s%s%s'", '%', serialize($n), '%');
    
    0 讨论(0)
  • 2020-11-29 08:09

    You may be looking for an SQL IN statement.

    http://www.w3schools.com/sql/sql_in.asp

    You'll have to break your array out a bit first, though. You can't just hand an array off to MySQL and expect it will know what to do with it. For that, you may try serializing it out with PHP's explode.

    http://php.net/manual/en/function.explode.php

    0 讨论(0)
  • 2020-11-29 08:10

    Working with php serialized data is obviously quite ugly, but I've got this one liner mix of MySQL functions that help to sort that out:

    select REPLACE(SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(searchColumn, 'fieldNameToExtract', -1), ';', 2), ':', -1), '"', '') AS extractedFieldName
    from tableName as t 
    having extractedFieldName = 'expressionFilter';
    

    Hope this can help!

    0 讨论(0)
提交回复
热议问题