It is possible to call PHP functions from SQLite. It makes it possible to use simple queries to 'normalize' the table.
I have converted the 'normalize comma delimited strings holding keys' to SQLite. see: (joining on ';' separated values in a column) for a more complete explanation
I started out looking for ways of converting the functions to run in SQLite. After some searching I came across this: Working with PHP UDFs in SQLite.
Which I found interesting - call PHP functions from SQLite. That sounds like fun!
It works but you cannot use PDO. You have to use the SQLite functions directly. Vendor Specific Database Extensions: SQLite3
Updated with your data (see previous edits for working code for other question)
The code:
<?php // Q34231542 -- count_in_set, value_in_set
/*
* See this question for a rather more complete explanation of what this is doing...
*
* https://stackoverflow.com/questions/33782728/can-i-resolve-this-with-pure-mysql-joining-on-separated-values-in-a-column/
*/
define('SQLITE_DB', __DIR__ .'/Q34231542.sqlite');
/**
* @var SQLite3
*/
$db = new SQLite3(SQLITE_DB);
/*
* Define the functions for use by SQLite.
*/
$db->createFunction('count_in_set', 'count_in_set', 2);
$db->createFunction('value_in_set', 'value_in_set', 3);
$sql ="
SELECT STRATEGY.STRATEGY_ID as 'applied_strategy_id',
STRATEGY.APPLIED_SET_IDS as 'applied_strategy_list',
isequence.id as 'which_strategy',
COUNT_IN_SET(STRATEGY.APPLIED_SET_IDS, ',') as 'StrategyCount',
VALUE_IN_SET(STRATEGY.APPLIED_SET_IDS, ',', isequence.id)
as 'TheStrategy',
ACTION_SET.VALUE as 'Action_Set_Value'
FROM STRATEGY
JOIN integerseries AS isequence
ON isequence.id <= COUNT_IN_SET(STRATEGY.APPLIED_SET_IDS, ',') /* normalize */
JOIN ACTION_SET
ON ACTION_SET.APPLIED_ACTION_SET_ID = VALUE_IN_SET(STRATEGY.APPLIED_SET_IDS, ',', isequence.id)
ORDER BY
STRATEGY.STRATEGY_ID , ACTION_SET.APPLIED_ACTION_SET_ID;
";
/*
* Run the query
*/
$stmt = $db->prepare($sql);
$result = $stmt->execute();
/*
* Get the results
*/
$rows = array();
while ($row = $result->fetchArray(SQLITE3_ASSOC)) { // fetch all the rows for now...
$rows[] = $row;
}
/*
* output...
*/
// \Kint::dump($rows);
echo '<pre>';
var_dump($rows);
echo '</pre>';
exit;
/* -------------------------------------------------------------------------
* The PHP functions called from SQLite
*/
/**
* Count the number of delimited items in a string
*
* @param string $delimitedValues
* @param string $delim
* @return integer
*/
function count_in_set($delimitedValues, $delim)
{
return substr_count(trim($delimitedValues, $delim), $delim) + 1;
}
/**
* Treat the delimited values as ONE BASED array.
*
* @param string $delimitedValues
* @param string $delim
* @param integer $which
* @return string
*/
function value_in_set($delimitedValues, $delim, $which)
{
$items = explode($delim, $delimitedValues);
return $items[$which - 1];
}
The output:
applied_strategy_id applied_strategy_list which_strategy StrategyCount TheStrategy Action_Set_Value
#1 1 "1,3,6,7" 1 4 "1" "X"
#2 1 "1,3,6,7" 2 4 "3" "Z"
#3 1 "1,3,6,7" 3 4 "6" "J"
#4 1 "1,3,6,7" 4 4 "7" "K"
#5 2 "1,2,4" 1 3 "1" "X"
#6 2 "1,2,4" 2 3 "2" "Y"
#7 2 "1,2,4" 3 3 "4" "H"
The data:
CREATE TABLE [integerseries] (
[id] INTEGER NOT NULL PRIMARY KEY);
INSERT INTO "integerseries" VALUES(1);
INSERT INTO "integerseries" VALUES(2);
INSERT INTO "integerseries" VALUES(3);
INSERT INTO "integerseries" VALUES(4);
INSERT INTO "integerseries" VALUES(5);
INSERT INTO "integerseries" VALUES(6);
INSERT INTO "integerseries" VALUES(7);
INSERT INTO "integerseries" VALUES(8);
INSERT INTO "integerseries" VALUES(9);
INSERT INTO "integerseries" VALUES(10);
CREATE TABLE STRATEGY (STRATEGY_ID INTEGER PRIMARY KEY, APPLIED_SET_IDS VARCHAR);
INSERT INTO "STRATEGY" VALUES(1,'1,3,6,7');
INSERT INTO "STRATEGY" VALUES(2,'1,2,4');
CREATE TABLE ACTION_SET (APPLIED_ACTION_SET_ID INTEGER PRIMARY KEY, VALUE VARCHAR);
INSERT INTO "ACTION_SET" VALUES(1,'X');
INSERT INTO "ACTION_SET" VALUES(2,'Y');
INSERT INTO "ACTION_SET" VALUES(3,'Z');
INSERT INTO "ACTION_SET" VALUES(4,'H');
INSERT INTO "ACTION_SET" VALUES(5,'I');
INSERT INTO "ACTION_SET" VALUES(6,'J');
INSERT INTO "ACTION_SET" VALUES(7,'K');
INSERT INTO "ACTION_SET" VALUES(8,'L');