所以首先我的mysql表定义如下:
订单(333000+条记录)
orders_id(PK),
customerName,
CompanyName,
Status,
shipping_no,
shipping_module,
tracking_no,
orders_status,
date_purchased..
Order_status (70条记录)
orders_status_id(pk),
language_id,
orders_status_name
orders_status_history (2220000+条记录)
`orders_status_history_id` int(11)
`orders_id` int(11)
`orders_status_id` int(5)
PRIMARY KEY (`orders_status_history_id`)
orders_status_history 表包含有关每个订单的不同状态
`orders_status_id` int(11)
`orders_status_name` varchar(32)
PRIMARY KEY (`orders_status_id`,`language_id`)
所以我想要得到的是下面描述的所有三个选项:
shipping_module
pickup_pickup或pickup2_pickup2 orders_status_history.orders_status_id
必须具有以下状态7,21,34,40 orders_status_history.orders_status_id
必须没有以下状态33,53 解释问题: 假设有10个订单,他们在生命中的某个时间有以下状态:
所以我要提取的订单是1,2,7,8因为这个订单包含7,31,21或40而不是53,33
我尝试过以下查询:
1)
SELECT *
FROM orders AS o, orders_status_history AS osh
WHERE (
o.shipping_module LIKE '%pickup_pickup%'
OR o.shipping_module LIKE '%pickup2_pickup2%'
)
AND o.orders_id = osh.orders_id
AND osh.orders_status_id
IN ( 7, 21, 31, 40 ) AND osh.orders_status_id
NOT IN (33, 53)
此查询可以正常运行,但它可以获得所有结果(1200条记录),但它没有过滤3选项
2)。
SELECT *
FROM orders AS o, orders_status_history AS osh
WHERE (
o.shipping_module LIKE '%pickup_pickup%'
OR o.shipping_module LIKE '%pickup2_pickup2%'
)
AND o.orders_id = osh.orders_id
AND osh.orders_status_id IN (7, 21, 31, 40)
AND osh.orders_status_id != 33
AND osh.orders_status_id != 53
它也像以前一样工作,没有过滤第3个选项
3。)
SELECT *
FROM orders AS o, orders_status_history AS osh
WHERE (
o.shipping_module LIKE '%pickup_pickup%'
OR o.shipping_module LIKE '%pickup2_pickup2%'
)
AND o.orders_id = osh.orders_id
AND osh.orders_status_id IN (7, 21, 31, 40)
AND osh.orders_status_id NOT IN (
SELECT so.orders_id
FROM orders AS so, orders_status_history AS sosh
WHERE (
so.shipping_module LIKE '%pickup_pickup%'
OR so.shipping_module LIKE '%pickup2_pickup2%'
)
AND sosh.orders_status_id != 33
)
此查询花费了太多时间来执行并且没有执行
4。)
SELECT *
FROM orders AS o, orders_status_history AS osh
WHERE (
o.shipping_module LIKE '%pickup_pickup%'
OR o.shipping_module LIKE '%pickup2_pickup2%'
)
AND o.orders_id = osh.orders_id
AND osh.orders_status_id = 7
AND osh.orders_status_id = 21
AND osh.orders_status_id = 31
AND osh.orders_status_id = 40
AND osh.orders_status_id != 33
AND osh.orders_status_id != 53
此查询首先作为查询未过滤第3个选项
所以后来我用php试试了
$sql = "SELECT o.orders_id, osh.orders_status_history_id
FROM
orders AS o,
orders_status_history AS osh
WHERE (
o.shipping_module LIKE '%pickup_pickup%'
OR o.shipping_module LIKE '%pickup2_pickup2%'
)
AND o.orders_id = osh.orders_id
AND osh.orders_status_id IN (7, 21, 31, 40)
AND osh.orders_status_id != 33
AND osh.orders_status_id != 53";
$sql = mysql_query($sql);
while ($row = mysql_fetch_array($sql)){
$row["orders_id"]);
if(getOrderStatus($row["orders_id"]))
echo "<br/>".$row["orders_id"];
}
function getOrderStatus($order){
$sql = "SELECT orders_status_id FROM orders_status_history WHERE orders_id = ".$order;
echo "<br/> Sql Query : ".$sql;
$sql = mysql_query($sql);
while ($status = mysql_fetch_array($sql))
if((int)$status["orders_status_id"] == 33 || (int)$status["orders_status_id"] == 53)
return false;
return true;
}
此代码占用的时间超过30米。我set_time_limit(0);
注意:我只能使用Mysql_ *,因为我们的php版本是4.9
答案 0 :(得分:2)
以下是获取符合条件的订单的一种方法:
SELECT o.orders_id
FROM orders o JOIN
orders_status_history osh
ON o.orders_id = osh.orders_id
WHERE (o.shipping_module LIKE '%pickup_pickup%' OR
o.shipping_module LIKE '%pickup2_pickup2%'
) AND
osh.orders_status_id IN (7, 21, 31, 40, 33, 53)
GROUP BY o.orders_id
HAVING SUM( osh.orders_status_id IN (33, 53) ) = 0;
WHERE
仅选择您关注的状态。 HAVING
确保您没有最后两个。
如果您需要订单或订单行的详细信息,则需要将这些表重新加入。