我正在mysql查询中加入表,它给了我重复的结果,因为在其中一个表上有2个结果。
这是我的查询。
$query_order = "
SELECT sfo.entity_id, sfo.status, sfo.created_at, sfo.customer_firstname, sfo.customer_lastname, sfo.customer_email, sfo.subtotal, sfo.shipping_amount, sfo.tax_amount, sfo.grand_total, sfo.total_paid, sfo.total_due, sfo.total_item_count,
sfoa.address_type, sfoa.firstname, sfoa.lastname, sfoa.street, sfoa.city, sfoa.region, sfoa.postcode, sfoa.telephone, sfoa.country_id,
sfoi.product_id, sfoi.name, sfoi.sku, sfoi.qty_ordered, sfoi.price, sfoi.original_price, sfoi.row_total, sfoi.additional_data as additional_data1,
sfst.track_number, sfst.carrier_code, sfst.title,
sfop.additional_data as additional_data2, sfop.amount_paid, sfop.amount_ordered
FROM sales_flat_order sfo
JOIN sales_flat_order_address sfoa
ON sfo.entity_id = sfoa.parent_id
JOIN sales_flat_order_item sfoi
ON sfo.entity_id = sfoi.order_id
JOIN sales_flat_shipment_track sfst
ON sfo.entity_id = sfst.order_id
JOIN sales_flat_order_payment sfop
ON sfo.entity_id = sfop.entity_id
WHERE sfo.increment_id = '" . $po . "'
LIMIT 0 , 30";
parent_id
sales_flat_order_address
有两个结果,因为其中一个是帐单邮寄地址,另一个是送货地址。这两个字段都具有相同的parent_id
值,这就是我加入表格的内容。
所有表都使用sales_flat_order sfo
中entity_id
的相同值加入,并且是该表的主键。
如何确保其他表格仅输出其字段中的值一次,同时确保我仍然可以从sales_flat_order_address
表中获取结算和送货地址?
我尝试了GROUP BY,它确实消除了重复项,但它也消除了sales_flat_order_address
表中的送货地址。
我应该使用子查询构建查询吗?我做了很多搜索,但到目前为止,我不确定如何处理我的特定情况。
2016年5月7日更新
我必须做的是为了允许显示计费和送货地址而不复制其他连接表中的其他字段我只是将地址表加入两次,以便while循环只循环一次而不是两次。
所以我将其添加到我的SELECT
sfoab.address_type as billing, sfoab.firstname as bfirst, sfoab.lastname as blast, sfoab.street as bstreet, sfoab.city as bcity, sfoab.region as bregion, sfoab.postcode as bzip, sfoab.telephone as btel, sfoab.country_id as bcountry,
sfoas.address_type as shipping, sfoas.firstname as sfirst, sfoas.lastname as slast, sfoas.street as sstreet, sfoas.city as scity, sfoas.region as sregion, sfoas.postcode as szip, sfoas.telephone as stel, sfoas.country_id as scountry,
然后我加入地址表两次
LEFT JOIN sales_flat_order_address sfoab
ON sfo.entity_id = sfoab.parent_id AND sfoab.address_type = 'billing'
LEFT JOIN sales_flat_order_address sfoas
ON sfo.entity_id = sfoas.parent_id AND sfoas.address_type = 'shipping'
然后最后在while循环中我的变量
$billing = ucfirst($row['billing']);
$billing_firstname = $row['bfirst'];
$billing_lastname = $row['blast'];
$billing_name = ucwords($billing_firstname . " " . $billing_lastname);
$billing_street = ucwords($row['bstreet']);
$billing_city = ucwords($row['bcity']);
$billing_region = $row['bregion'];
$billing_postcode = $row['bzip'];
$billing_telephone = $row['btel'];
$billing_country = $countries[$row['bcountry']];
$shipping = ucfirst($row['shipping']);
$shipping_firstname = $row['sfirst'];
$shipping_lastname = $row['slast'];
$shipping_name = ucwords($shipping_firstname . " " . $shipping_lastname);
$shipping_street = ucwords($row['sstreet']);
$shipping_city = ucwords($row['scity']);
$shipping_region = $row['sregion'];
$shipping_postcode = $row['szip'];
$shipping_telephone = $row['stel'];
$shipping_country = $countries[$row['scountry']];
其他人的建议是使用GROUP BY或DISTINCT。当我使用这些方法时,它不会显示结算和送货地址。它只会显示结算而非送货地址。
当我离开这些方法时,显示结算和发货,但这会导致其他表中的其他字段输出两次。
所以我找到的唯一解决方案是两次加入地址表。这样做我得到了我想要的东西。并且while循环不循环两次以获得两种地址类型。
如果您知道更好或更有效的方法,请告诉我们。我是MySQL查询和while循环的新手。
答案 0 :(得分:0)
您可以尝试使用Unique Column进行分组:像这样吗?
<?php
//THE ONLY ADDITION HERE IS THE "GROUP BY" CLAUSE
//OTHERWISE THIS IS YOUR OWN CODE WITH THE EXCEPTION OF FORMATTING...
$query_order = "
SELECT
sfo.entity_id,
sfo.status,
sfo.created_at,
sfo.customer_firstname,
sfo.customer_lastname,
sfo.customer_email,
sfo.subtotal,
sfo.shipping_amount,
sfo.tax_amount,
sfo.grand_total,
sfo.total_paid,
sfo.total_due,
sfo.total_item_count,
sfoa.address_type,
sfoa.firstname,
sfoa.lastname,
sfoa.street,
sfoa.city,
sfoa.region,
sfoa.postcode,
sfoa.telephone,
sfoa.country_id,
sfoi.product_id,
sfoi.name,
sfoi.sku,
sfoi.qty_ordered,
sfoi.price,
sfoi.original_price,
sfoi.row_total,
sfoi.additional_data as additional_data1,
sfst.track_number,
sfst.carrier_code,
sfst.title,
sfop.additional_data as additional_data2,
sfop.amount_paid,
sfop.amount_ordered
FROM sales_flat_order_address sfoa,
sales_flat_order sfo
JOIN sales_flat_order_item sfoi
ON sfo.entity_id = sfoi.order_id
JOIN sales_flat_order_item sfoi
ON sfo.entity_id = sfoi.order_id
JOIN sales_flat_shipment_track sfst
ON sfo.entity_id = sfst.order_id
LEFT JOIN sales_flat_order_payment sfop
ON sfo.entity_id = sfop.entity_id
WHERE sfo.increment_id = " . (int)$po . "
GROUP BY sfo.entity_id
LIMIT 0 , 30";
取决于你想要达到的目标; LEFT JOIN可能会派上用场:
$query_order = "
SELECT
sfo.entity_id,
sfo.status,
sfo.created_at,
sfo.customer_firstname,
sfo.customer_lastname,
sfo.customer_email,
sfo.subtotal,
sfo.shipping_amount,
sfo.tax_amount,
sfo.grand_total,
sfo.total_paid,
sfo.total_due,
sfo.total_item_count,
sfoa.address_type,
sfoa.firstname,
sfoa.lastname,
sfoa.street,
sfoa.city,
sfoa.region,
sfoa.postcode,
sfoa.telephone,
sfoa.country_id,
sfoi.product_id,
sfoi.name,
sfoi.sku,
sfoi.qty_ordered,
sfoi.price,
sfoi.original_price,
sfoi.row_total,
sfoi.additional_data as additional_data1,
sfst.track_number,
sfst.carrier_code,
sfst.title,
sfop.additional_data as additional_data2,
sfop.amount_paid,
sfop.amount_ordered
FROM sales_flat_order_address sfoa,
sales_flat_order sfo
LEFT JOIN sales_flat_order_item sfoi
ON sfo.entity_id = sfoi.order_id
LEFT JOIN sales_flat_shipment_track sfst
ON sfo.entity_id = sfst.order_id
LEFT JOIN sales_flat_order_payment sfop
ON sfo.entity_id = sfop.entity_id
WHERE sfo.increment_id = " . (int)$po . "
GROUP BY sfo.entity_id
LIMIT 0 , 30";
我希望这有点帮助...