MYSQL连接查询多个表显示某些字段的重复结果

时间:2016-05-04 04:41:17

标签: php mysql join duplicates

我正在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 sfoentity_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循环的新手。

1 个答案:

答案 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";

我希望这有点帮助...