626
Tengo 2 tablas como a continuación
Tabla de notas
╔══════════╦═════════════════╗
║ nid ║ forDepts ║
╠══════════╬═════════════════╣
║ 1 ║ 1,2,4 ║
║ 2 ║ 4,5 ║
╚══════════╩═════════════════╝
Tabla de Posiciones
╔══════════╦═════════════════╗
║ id ║ name ║
╠══════════╬═════════════════╣
║ 1 ║ Executive ║
║ 2 ║ Corp Admin ║
║ 3 ║ Sales ║
║ 4 ║ Art ║
║ 5 ║ Marketing ║
╚══════════╩═════════════════╝
Estoy buscando consultar mi tabla de Notas y asociar la columna ‘forDepts’ con valores de la tabla de Posiciones.
La salida debe ser:
╠══════════╬════════════════════════════╣
║ 1 ║ Executive, Corp Admin, Art ║
║ 2 ║ Art, Marketing ║
╚══════════╩════════════════════════════╝
Sé que la base de datos debe normalizarse, pero no puedo cambiar la estructura de la base de datos para este proyecto.
Esto se utilizará para exportar un archivo de Excel con el siguiente código.
<?PHP
$dbh1 = mysql_connect($hostname, $username, $password);
mysql_select_db('exAdmin', $dbh1);
function cleanData(&$str)
{
$str = preg_replace("/\t/", "\\t", $str);
$str = preg_replace("/\r?\n/", "\\n", $str);
if(strstr($str, '"')) $str=""" . str_replace('"', '""', $str) . '"';
}
$filename = "eXteres_summary_" . date('m/d/y') . ".xls";
header("Content-Disposition: attachment; filename=\"$filename\"");
header("Content-Type: application/vnd.ms-excel");
//header("Content-Type: text/plain");
$flag = false;
$result = mysql_query(
"SELECT p.name, c.company, n.nid, n.createdOn, CONCAT_WS(' ',c2.fname,c2.lname), n.description
FROM notes n
LEFT JOIN Positions p ON p.id = n.forDepts
LEFT JOIN companies c ON c.userid = n.clientId
LEFT JOIN companies c2 ON c2.userid = n.createdBy"
, $dbh1);
while(false !== ($row = mysql_fetch_assoc($result))) {
if(!$flag) {
$colnames = array(
'Created For' => "Created For",
'Company' => "Company",
'Case ID' => "Case ID",
'Created On' => "Created On",
'Created By' => "Created By",
'Description' => "Description"
);
// display field/column names as first row
echo implode("\t", array_keys($colnames)) . "\r\n";
$flag = true;
}
$row['createdOn'] = date('m-d-Y | g:i a', strtotime($row['createdOn']));
array_walk($row, 'cleanData');
echo implode("\t", array_values($row)) . "\r\n";
}
exit;
?>
Este código genera solo el primer valor de ‘forDepts’
Exa: Ejecutivo (en lugar de Ejecutivo, Corp Admin, Art)
¿Se puede lograr esto mediante CONCAT o FIND_IN_SET?
SELECT a.nid,
GROUP_CONCAT(b.name ORDER BY b.id) DepartmentName
FROM Notes a
INNER JOIN Positions b
ON FIND_IN_SET(b.id, a.forDepts) > 0
GROUP BY a.nid
-
Si una fila en el
Notes
la tabla tiene un valor en blanco para la columnaforDepts
entonces resulta que falta esa fila.– Kishor Patidar
20 de agosto de 2019 a las 11:10
-
@JohnWoo ¿Cuál es el propósito de
> 0
al final de la unión? ¿Está eso relacionado con el rendimiento?– Silambarasan RD
29 de noviembre de 2020 a las 11:12
Tirthraj Singh Bartwal
Table 1
╔══════════╦═════════════════╗
║ nid ║ forDepts ║
╠══════════╬═════════════════╣
║ 1 ║ 1,2,4 ║
║ 2 ║ 4,5 ║
╚══════════╩═════════════════╝
Table 2
╔══════════╦═════════════════╗
║ id ║ name ║
╠══════════╬═════════════════╣
║ 1 ║ Executive ║
║ 2 ║ Corp Admin ║
║ 3 ║ Sales ║
║ 4 ║ Art ║
║ 5 ║ Marketing ║
╚══════════╩═════════════════╝
SELECT * FROM table1 as t1 LEFT JOIN table2 as t2 ON find_in_set(t2.id,
t1.forDepts)
Output
╠══════════╬════════════════════════════╣
║ 1 ║ Executive, Corp Admin, Art ║
║ 2 ║ Art, Marketing ║
╚══════════╩════════════════════════════╝
-
Debes agregar una explicación a tu respuesta.
– deW1
29 de abril de 2015 a las 10:11
-
El problema con este enfoque es que la consulta tarda años en completarse cuando hay una gran cantidad de datos.
– Kay Kay
5 de enero de 2020 a las 16:48
Si no puede cambiar el diseño incorrecto de la base de datos, probablemente debería arreglarlo FUERA de la base de datos, es decir, consulta los datos que obtiene e intercambia los identificadores con sus valores de texto en PHP antes de enviarlos al archivo de Excel. Lamentablemente, el diseño desagradable de la base de datos lo obliga a crear un código de corrección de diseño desagradable.
– Sven
30 de septiembre de 2013 a las 18:52