我的问题是我正在撰写的客户服务数据库。我对sql查询知之甚少,而且我真的很难获得正确的查询。
我有两张桌子:
**Customers:**
idcustomer
company_name
tel_number
address
postcode
**customer_machines**
id_customer_machine
id_customer
date_last_service
date_service_due
我想选择一些结果,显示在给定的一组日期(例如第9个月到期的机器)之间服务应该到哪台机器。
SELECT customer_machines.* from customer_machines WHERE (customer_machines.date_next_service BETWEEN '2013-09-01' AND '2013-10-01') ORDER BY date_next_service ASC;
这很好,但有些客户有多台机器,例如
+---------------------+-------------+-------------------+-------------------+
| id_customer_machine | id_customer | date_last_service | date_next_service |
+---------------------+-------------+-------------------+-------------------+
| 1 | 1 | 2012-09-02 | 2013-09-02 |
| 2 | 2 | 2012-09-14 | 2013-09-14 |
| 3 | 3 | 2012-09-30 | 2013-09-30 |
| 5 | 3 | 2012-09-30 | 2013-09-30 |
+---------------------+-------------+-------------------+-------------------+
我需要对客户拥有它们的机器进行分组,加入客户的详细信息并输出到浏览器中的表格,如:
Customer 1 address of customer 1 tel of customer 1 postcode of customer 1
machine-id-1 date-last-service date-next-service
------------------------------------------------------------------------------------
customer 2 address of customer 2 tel of customer 2 postcode of customer 2
machine-id-2 date-last-service date-next-service
-------------------------------------------------------------------------------------
customer 3 address of customer 3 tel of customer 3 postcode of customer 3
machine-id-3 date-last-service date-next-service
machine-id-5 date-last-service date-next-service
我可以使用单个查询将结果排列在一起吗?到目前为止,我只在php中尝试嵌套查询但没有成功。
如果你能指出我的方向很好
感谢
答案 0 :(得分:0)
SQL没有构建嵌套结果的功能,只有普通表。
在一些简单的情况下,您可以使用GROUP_CONCAT
来连接值。例如:
SELECT
id_customer,
GROUP_CONCAT(id_customer_machine SEPARATOR ', ') as id_customer_machines
FROM customer_machines;
会输出你:
+-------------+----------------------+
| id_customer | id_customer_machines |
+------------------------------------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3, 5 |
+-------------+----------------------+
但是,由于您需要对多个列进行分组,这对您没有帮助。 在您的情况下,您有两个选择:
答案 1 :(得分:0)
一种选择是从两个表中选择相关数据,例如:
SELECT c.*, cm.id_customer_machine, cm.date_last_service, cm.date_service_due from Customers c, customer_machines cm WHERE c.idcustomer = cm.customer_id AND (customer_machines.date_next_service BETWEEN '2013-09-01' AND '2013-10-01') ORDER BY date_next_service ASC;
然而,这可能并不理想,因为对于找到的每台机器,您最终也会得到重复的客户数据。
作为替代方案,您可以遍历每个客户并根据用户ID从第二个表中选择所有结果,并将其构建到数组或对象中,例如:
$customerArr = array();
$con=mysqli_connect("localhost","user","pass","schema");
$customerResult = mysqli_query($con,"SELECT * FROM Customers");
while($customerRow = mysqli_fetch_array($customerResult)){
$customerArr[$customerRow['idcustomer']];
$macineResult = mysqli_query($con,"SELECT * FROM customer_machines WHERE customer_id = 'customerRow['idcustomer']'");
while($machineRow = mysqli_fetch_array($machineResult)){
$customerArr[$customerRow['idcustomer']][$machineRow['id_customer_machine']]['date_last_service'] = $machineRow['date_last_service'];
$customerArr[$customerRow['idcustomer']][$machineRow['id_customer_machine']]['date_next_service'] = $machineRow['date_next_service'];
}
}
希望这有帮助。
答案 2 :(得分:0)
您可以使用单个查询执行此操作,但PHP代码中的循环将比使用单独的查询更复杂
SELECT * from customer_machines
INNER JOIN customers USING(customer_id)
WHERE (customer_machines.date_next_service BETWEEN '2013-09-01' AND '2013-10-01')
ORDER BY date_next_service ASC;
这应该给你类似的东西:
customer_id | machine_id | company_name | etc | other column | more data | ...
1 | 1 | xxxx
2 | 2 | xxxx
3 | 3 | xxxx
3 | 5 | xxxx
你的循环:
while($row = mysql_fetch_array($query)) {
$data[ $row[customer_id][] = $row;
}
这会给你一个类似于:
的数组array(
[1] => array(
[0] => array(
[company_name] => name,
the remaining customer and machine data
)
),
[2] => array(
[0] => array(
[company_name] => name,
the remaining customer and machine data
)
),
[3] => array(
[0] => array(
[company_name] => name,
the remaining customer and machine data
),
[1] => array(
[company_name] => name,
the remaining customer and machine data
)
)
只需迭代该数组即可打印数据;你需要2个循环才能做到这一点。
另一个解决方案是首先选择所有客户,循环选择并预先指示客户选择要显示的机器信息。这样做会得到很多疑问。