在此fiddle中,查询可以完美地创建动态支点。我从this线程的成员bluefeet中获取了查询,并在我自己的表模式中对其进行了测试。
SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'MAX(IF(a.attr_name = ''',
attr_name,
''', a.attr_value, NULL)) AS ',
attr_name
)
) INTO @sql
FROM attr;
SET @sql = CONCAT('SELECT p.model_id
, p.model_name
, ', @sql, '
from model p
left join model_attr t
on p.model_id = t.model_id
left join attr a
on t.attr_id = a.attr_id
GROUP BY p.model_id
, p.model_name');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
但是在我的实际代码中,即使没有对查询进行修改,它也会引发语法错误:
[You have an error in your SQL syntax;
check the manual that corresponds to your MySQL server version for the right syntax
to use near 'SELECT GROUP_CONCAT(DISTINCT CONCAT( 'MAX(IF(a.attr_name = ''', ' at line 2]
这是实际的代码:
$id = $_GET["id"];
function querySelect($sql,&$rows)
{
$link = database_link();
$result = mysqli_query($link,$sql);
$rows = array();
while($row = mysqli_fetch_array($result,MYSQLI_ASSOC))
{
$rows[] = $row;
}
return mysqli_num_rows($result);
}
$sql = "
SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'MAX(IF(a.attr_name = ''',
attr_name,
''', a.attr_value, NULL)) AS ',
attr_name
)
) INTO @sql
FROM attr;
SET @sql = CONCAT('SELECT p.model_id
, p.model_name
, ', @sql, '
from model p
left join model_attr t
on p.model_id = t.model_id
left join attr a
on t.attr_id = a.attr_id
GROUP BY p.model_id
, p.model_name');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
";
querySelect($sql,$rows);
我也尝试过PDO方法,但它会抛出SQLSTATE[HY000]: General error
。查询与mysql不兼容吗?如果是这样,你有其他选择吗?
try
{
$dbh = new PDO("mysql:host=$hostname;dbname=$databasename", $username, $password);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "
SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'MAX(IF(a.attr_name = ''',
attr_name,
''', a.attr_value, NULL)) AS ',
attr_name
)
) INTO @sql
FROM attr;
SET @sql = CONCAT('SELECT p.model_id
, p.model_name
, ', @sql, '
from model p
left join model_attr t
on p.model_id = t.model_id
left join attr a
on t.attr_id = a.attr_id
GROUP BY p.model_id
, p.model_name');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
";
$users = $dbh->prepare($sql);
$users->execute();
$results = $users->fetchAll();
foreach($results as $result)
{
echo '<div>".$result["model_name"]."</div>';
}
$dbh = null;
}
catch(PDOException $e)
{
echo $e->getMessage();
}
答案 0 :(得分:2)
您的查询包含六个sql语句。您可以使用mysqli :: multi_query()一次执行这六个语句,也可以分别执行这六个语句:
第一句话:
SET @sql = NULL;
第二个陈述
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'MAX(IF(a.attr_name = ''',
attr_name,
''', a.attr_value, NULL)) AS ',
attr_name
)
) INTO @sql
FROM attr;
第三声明
SET @sql = CONCAT('SELECT p.model_id
, p.model_name
, ', @sql, '
from model p
left join model_attr t
on p.model_id = t.model_id
left join attr a
on t.attr_id = a.attr_id
GROUP BY p.model_id
, p.model_name');
第四:
PREPARE stmt FROM @sql;
下一个是具有所需结果集的那个:
EXECUTE stmt;
第六个也是最后一个:
DEALLOCATE PREPARE stmt;
只要您使用相同的连接,您的用户变量就会保持不变。也许最好从生成的SELECT语句创建一个视图,以便以后重用。
基本代码(没有任何错误检查)
$sql = "SET @sql = NULL;";
$result = mysqli_query($link, $sql); // execute first statement
$sql = "SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'MAX(IF(a.attr_name = ''',
attr_name,
''', a.attr_value, NULL)) AS ',
attr_name
)
) INTO @sql
FROM attr;";
$result = mysqli_query($link, $sql); // the second statement
$sql = "SET @sql = CONCAT('SELECT p.model_id
, p.model_name
, ', @sql, '
from model p
left join model_attr t
on p.model_id = t.model_id
left join attr a
on t.attr_id = a.attr_id
GROUP BY p.model_id
, p.model_name');";
$result = mysqli_query($link, $sql); // the third one
$sql = "PREPARE stmt FROM @sql;";
$result = mysqli_query($link, $sql); // prepare the real query
$sql = "EXECUTE stmt;"; // Attention, we execute the generated query
querySelect($sql,$rows); // your function to extract the desired result
$sql = "DEALLOCATE PREPARE stmt;";
$result = mysqli_query($link, $sql); // clean up
使用PHP 5.3和PDO,你应该可以一次执行它:看看PDO support for multiple queries (PDO_MYSQL, PDO_MYSQLND)。