一个硬 SQL 查询
A hard SQL Query
我有一个不寻常的 SQL 问题,我不太确定如何最好地解释,所以请耐心等待。我有三个table,一个是志愿者组织,一个是用户,一个是用户详情。
#Table 1#
## Name President Secretary Treasurer
----------
ABC 571 123 456
DEF 457 582 444
#Table 2#
## Id Name
----------
571 Joe Blogs
123 Joanne Blogs
#Table 3#
## Id Address City
----------
571 123...... Somewhere
123 456..... Somewhere Else
我想做的是允许用户按组织名称的顺序 assemble PDF 地址标签,所以他们可能会说他们想要每个组织的总裁或总裁和秘书,所以它将读取所有组织的总裁和秘书 ID,并将它们加入到地址详细信息中,并按组织的顺序 assemble。他们可以选择只做总裁或总裁和秘书或以上的任何组合。它必须按组织顺序和 return 用户对象排序。
例如
ABC -> President
ABC -> Secretary
DEF -> President
DEF -> Secretary
我已经尝试了几个选项。第一个是,
$query = $db->getQuery(true);
$query->select($db->quoteName('a.name'));
$query->select($db->quoteName($this->show_exec));
$query->from($db->quoteName('#__agshows_shows', 'a'));
$tableACount = 'b';
$tableBCount = 'aa';
foreach($this->show_exec as $column){
$query->select($db->quoteName(array($tableACount . '.user_id', $tableACount . '.address_1', $tableACount . '.address_2', $tableACount . '.city', $tableACount . '.region', $tableACount . '.postal_code', $tableBCount . '.name')))
->join('LEFT', $db->quoteName('#__agshows_user_profile', $tableACount) . ' ON (' . $db->quoteName($tableACount . '.user_id') . ' = ' . $db->quoteName($column) . ')')
->join('LEFT', $db->quoteName('#__users', $tableBCount) . ' ON (' . $db->quoteName($tableBCount . '.id') . ' = ' . $db->quoteName($column) . ')');
$tableACount ++;
$tableBCount ++;
}
switch($this->show_sort) {
case 'a.title':
$query->order($db->quoteName('a.title') . ' ASC');
break;
case 'a.groupid':
$query->order($db->quoteName('a.groupid') . ' ASC');
break;
default:
$query->order($db->quoteName('a.title') . ' ASC');
}
$db->setQuery($query);
$show_users = $db->loadObjectList();
这个问题是因为它通过 foreach 循环为每个组织相互覆盖。我希望它是灵活的($this->show_exec 包含一组可供选择的列,即 a.president、a.secretary)。
第二个选项是,
if(!empty($this->show_exec)) {
// Get the Show Exec user IDs.
$query = $db->getQuery(true);
$query->select($db->quoteName($this->show_exec));
$query->from($db->quoteName('#__agshows_shows'));
$db->setQuery($query);
$show_users = $db->loadAssocList();
foreach ($show_users as $shows) {
foreach ($shows as $key=>$value) {
if($value != 0) {
$user_ids[]=$value;
}
}
}
}
$query = $db->getQuery(true);
$query->select('a.*');
$query->from($db->quoteName('#__agshows_user_profile') . ' AS a');
// Join over the users names.
$query->select('uc.name')
->join('LEFT', '#__users AS uc ON uc.id=a.user_id');
$query->where('a.user_id IN ('. implode(',', $user_ids) . ')');
$query->order($db->escape('a.city asc'));
$db->setQuery($query);
$recipients = $db->loadObjectList();
这个问题是 $users_id 的顺序是正确的,但是当它查询第二个 table 时,它没有参考排序依据,只是 returns按照第二个的顺序 table 不是我想要的顺序....
有没有一种简洁的方法可以将所有这些都合而为一?
或者有什么方法可以将第二个查询排序为 return 结果按照 $user_ids 数组的顺序?
我希望这是有道理的..
谢谢
我认为以下查询可能适合您:
SELECT
*
FROM
(SELECT
o.name AS org_name,
u1.name AS username,
'president' AS `type`
FROM
org o
LEFT JOIN users u1
ON u1.`id` = o.`president`
UNION
ALL
SELECT
o.name AS org_name,
u1.name AS username,
'secretary' AS `type`
FROM
org o
LEFT JOIN users u1
ON u1.`id` = o.`secretary`
UNION
ALL
SELECT
o.name AS org_name,
u1.name AS username,
'treasurer' AS `type`
FROM
org o
LEFT JOIN users u1
ON u1.`id` = o.`treasurer`) AS a
ORDER BY a.org_name ;
我假定用户 table 的主键将用作组织 table 的总裁、秘书和财务主管列的外键。
下面的查询输出将生成一个虚拟列 "type",您可以在代码中使用它来确定该特定用户在组织中的角色。此外,您还需要动态创建此查询,以应对仅需要总裁或秘书或财务主管或他们的任意组合的情况。
我有一个不寻常的 SQL 问题,我不太确定如何最好地解释,所以请耐心等待。我有三个table,一个是志愿者组织,一个是用户,一个是用户详情。
#Table 1#
## Name President Secretary Treasurer
----------
ABC 571 123 456
DEF 457 582 444
#Table 2#
## Id Name
----------
571 Joe Blogs
123 Joanne Blogs
#Table 3#
## Id Address City
----------
571 123...... Somewhere
123 456..... Somewhere Else
我想做的是允许用户按组织名称的顺序 assemble PDF 地址标签,所以他们可能会说他们想要每个组织的总裁或总裁和秘书,所以它将读取所有组织的总裁和秘书 ID,并将它们加入到地址详细信息中,并按组织的顺序 assemble。他们可以选择只做总裁或总裁和秘书或以上的任何组合。它必须按组织顺序和 return 用户对象排序。
例如
ABC -> President
ABC -> Secretary
DEF -> President
DEF -> Secretary
我已经尝试了几个选项。第一个是,
$query = $db->getQuery(true);
$query->select($db->quoteName('a.name'));
$query->select($db->quoteName($this->show_exec));
$query->from($db->quoteName('#__agshows_shows', 'a'));
$tableACount = 'b';
$tableBCount = 'aa';
foreach($this->show_exec as $column){
$query->select($db->quoteName(array($tableACount . '.user_id', $tableACount . '.address_1', $tableACount . '.address_2', $tableACount . '.city', $tableACount . '.region', $tableACount . '.postal_code', $tableBCount . '.name')))
->join('LEFT', $db->quoteName('#__agshows_user_profile', $tableACount) . ' ON (' . $db->quoteName($tableACount . '.user_id') . ' = ' . $db->quoteName($column) . ')')
->join('LEFT', $db->quoteName('#__users', $tableBCount) . ' ON (' . $db->quoteName($tableBCount . '.id') . ' = ' . $db->quoteName($column) . ')');
$tableACount ++;
$tableBCount ++;
}
switch($this->show_sort) {
case 'a.title':
$query->order($db->quoteName('a.title') . ' ASC');
break;
case 'a.groupid':
$query->order($db->quoteName('a.groupid') . ' ASC');
break;
default:
$query->order($db->quoteName('a.title') . ' ASC');
}
$db->setQuery($query);
$show_users = $db->loadObjectList();
这个问题是因为它通过 foreach 循环为每个组织相互覆盖。我希望它是灵活的($this->show_exec 包含一组可供选择的列,即 a.president、a.secretary)。
第二个选项是,
if(!empty($this->show_exec)) {
// Get the Show Exec user IDs.
$query = $db->getQuery(true);
$query->select($db->quoteName($this->show_exec));
$query->from($db->quoteName('#__agshows_shows'));
$db->setQuery($query);
$show_users = $db->loadAssocList();
foreach ($show_users as $shows) {
foreach ($shows as $key=>$value) {
if($value != 0) {
$user_ids[]=$value;
}
}
}
}
$query = $db->getQuery(true);
$query->select('a.*');
$query->from($db->quoteName('#__agshows_user_profile') . ' AS a');
// Join over the users names.
$query->select('uc.name')
->join('LEFT', '#__users AS uc ON uc.id=a.user_id');
$query->where('a.user_id IN ('. implode(',', $user_ids) . ')');
$query->order($db->escape('a.city asc'));
$db->setQuery($query);
$recipients = $db->loadObjectList();
这个问题是 $users_id 的顺序是正确的,但是当它查询第二个 table 时,它没有参考排序依据,只是 returns按照第二个的顺序 table 不是我想要的顺序....
有没有一种简洁的方法可以将所有这些都合而为一?
或者有什么方法可以将第二个查询排序为 return 结果按照 $user_ids 数组的顺序?
我希望这是有道理的..
谢谢
我认为以下查询可能适合您:
SELECT
*
FROM
(SELECT
o.name AS org_name,
u1.name AS username,
'president' AS `type`
FROM
org o
LEFT JOIN users u1
ON u1.`id` = o.`president`
UNION
ALL
SELECT
o.name AS org_name,
u1.name AS username,
'secretary' AS `type`
FROM
org o
LEFT JOIN users u1
ON u1.`id` = o.`secretary`
UNION
ALL
SELECT
o.name AS org_name,
u1.name AS username,
'treasurer' AS `type`
FROM
org o
LEFT JOIN users u1
ON u1.`id` = o.`treasurer`) AS a
ORDER BY a.org_name ;
我假定用户 table 的主键将用作组织 table 的总裁、秘书和财务主管列的外键。
下面的查询输出将生成一个虚拟列 "type",您可以在代码中使用它来确定该特定用户在组织中的角色。此外,您还需要动态创建此查询,以应对仅需要总裁或秘书或财务主管或他们的任意组合的情况。