检查子查询结果是否存在,然后减去它
Check if subquery result exists and then subtract it
我有一个大查询,我必须减去子查询值。我尝试了 JOINS,但它们无法正常工作,因为有多个分组会导致不正确的数学方程式结果。查询:
SELECT
o.order_id,
sa.shipping_name AS user,
ROUND(SUM(op.price * op.amount) + o.shipping_price - IF(EXISTS(SELECT SUM(od.discount) FROM order_discounts od WHERE od.order_id=o.order_id GROUP BY od.order_id), (SELECT SUM(od.discount) FROM order_discounts od WHERE od.order_id=o.order_id GROUP BY od.order_id), 0), 2)
AS order_total FROM
( orders o JOIN order_products op ON op.order_id=o.order_id )
LEFT OUTER JOIN shipping_addresses sa ON o.shipping_address_id = sa.shipping_address_id
GROUP BY o.order_id ORDER BY o.order_date DESC, o.user_id DESC
如您所见,我必须 运行 查询以检查是否有折扣,然后再次 运行 以减去折扣。所以我的问题是我怎样才能得到“SELECT SUM(od.discount)...”部分一次?
表的结构:
CREATE TABLE `orders` (
`order_id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`order_date` datetime NOT NULL,
`shipping_address_id` int(11) NOT NULL,
`shipping_price` float NOT NULL,
`shipping_option_id` int(11) NOT NULL,
`order_currency` varchar(5) CHARACTER SET utf8mb4 NOT NULL,
`billing_address_id` int(11) NOT NULL,
`status` enum('unpaid','paid','shipped') CHARACTER SET utf8mb4 NOT NULL,
`admin_id` int(11) NOT NULL,
`descr` text CHARACTER SET utf8mb4 NOT NULL,
`payment_type` varchar(255) CHARACTER SET utf8mb4 NOT NULL,
`invoice_url` varchar(255) CHARACTER SET utf8mb4 NOT NULL,
`amount_paid` double NOT NULL,
`stripe_src_id` varchar(50) NOT NULL,
`ipn_message` text NOT NULL,
`stripe_client_secret` varchar(255) NOT NULL,
`order_total` double NOT NULL,
`paid_via` enum('paypal','stripe','bancontact') NOT NULL,
`order_notes` text CHARACTER SET utf8mb4 NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `order_discounts`
--
CREATE TABLE `order_discounts` (
`order_id` int(11) NOT NULL,
`discount_id` int(11) NOT NULL,
`discount` float NOT NULL,
`currency` varchar(5) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
-- --------------------------------------------------------
--
-- Table structure for table `order_products`
--
CREATE TABLE `order_products` (
`op_id` int(11) NOT NULL,
`order_id` int(11) NOT NULL,
`product_id` int(11) NOT NULL,
`amount` int(7) NOT NULL,
`price` double NOT NULL,
`currency` varchar(5) CHARACTER SET utf8mb4 NOT NULL,
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `shipping_addresses`
--
CREATE TABLE `shipping_addresses` (
`shipping_address_id` int(11) NOT NULL,
`shipping_name` varchar(255) CHARACTER SET utf8mb4 NOT NULL,
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
order_products
和 order_discounts
中的 似乎每个 order_id
都有几行。如果是这样,我建议在子查询中聚合:
select
o.order_id,
sa.shipping_name as user,
round(op.value - coalesce(od.value, 0), 2) order_total
from orders o
inner join (
select order_id, sum(price * amount) value
from order_products op
group by order_id
) op on op.order_id = o.order_id
left join (
select order_id, sum(discount) value
from order_discounts
group by order_id
) od on od.order_id = o.order_id
left join shipping_addresses sa
on o.shipping_address_id = sa.shipping_address_id
order by o.order_date desc, o.user_id desc
您还可以使用子查询:
select
o.order_id,
sa.shipping_name as user,
round(
(
select sum(op.price * op.amount)
from order_products op
where op.order_id = o.order_id
)
- (
select coalesce(sum(od.discount), 0)
from order_discounts od
where od.order_id = o.order_id
),
2
) order_total
from orders o
left join shipping_addresses sa
on o.shipping_address_id = sa.shipping_address_id
order by o.order_date desc, o.user_id desc
我有一个大查询,我必须减去子查询值。我尝试了 JOINS,但它们无法正常工作,因为有多个分组会导致不正确的数学方程式结果。查询:
SELECT
o.order_id,
sa.shipping_name AS user,
ROUND(SUM(op.price * op.amount) + o.shipping_price - IF(EXISTS(SELECT SUM(od.discount) FROM order_discounts od WHERE od.order_id=o.order_id GROUP BY od.order_id), (SELECT SUM(od.discount) FROM order_discounts od WHERE od.order_id=o.order_id GROUP BY od.order_id), 0), 2)
AS order_total FROM
( orders o JOIN order_products op ON op.order_id=o.order_id )
LEFT OUTER JOIN shipping_addresses sa ON o.shipping_address_id = sa.shipping_address_id
GROUP BY o.order_id ORDER BY o.order_date DESC, o.user_id DESC
如您所见,我必须 运行 查询以检查是否有折扣,然后再次 运行 以减去折扣。所以我的问题是我怎样才能得到“SELECT SUM(od.discount)...”部分一次?
表的结构:
CREATE TABLE `orders` (
`order_id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`order_date` datetime NOT NULL,
`shipping_address_id` int(11) NOT NULL,
`shipping_price` float NOT NULL,
`shipping_option_id` int(11) NOT NULL,
`order_currency` varchar(5) CHARACTER SET utf8mb4 NOT NULL,
`billing_address_id` int(11) NOT NULL,
`status` enum('unpaid','paid','shipped') CHARACTER SET utf8mb4 NOT NULL,
`admin_id` int(11) NOT NULL,
`descr` text CHARACTER SET utf8mb4 NOT NULL,
`payment_type` varchar(255) CHARACTER SET utf8mb4 NOT NULL,
`invoice_url` varchar(255) CHARACTER SET utf8mb4 NOT NULL,
`amount_paid` double NOT NULL,
`stripe_src_id` varchar(50) NOT NULL,
`ipn_message` text NOT NULL,
`stripe_client_secret` varchar(255) NOT NULL,
`order_total` double NOT NULL,
`paid_via` enum('paypal','stripe','bancontact') NOT NULL,
`order_notes` text CHARACTER SET utf8mb4 NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `order_discounts`
--
CREATE TABLE `order_discounts` (
`order_id` int(11) NOT NULL,
`discount_id` int(11) NOT NULL,
`discount` float NOT NULL,
`currency` varchar(5) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
-- --------------------------------------------------------
--
-- Table structure for table `order_products`
--
CREATE TABLE `order_products` (
`op_id` int(11) NOT NULL,
`order_id` int(11) NOT NULL,
`product_id` int(11) NOT NULL,
`amount` int(7) NOT NULL,
`price` double NOT NULL,
`currency` varchar(5) CHARACTER SET utf8mb4 NOT NULL,
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `shipping_addresses`
--
CREATE TABLE `shipping_addresses` (
`shipping_address_id` int(11) NOT NULL,
`shipping_name` varchar(255) CHARACTER SET utf8mb4 NOT NULL,
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
order_products
和 order_discounts
中的 似乎每个 order_id
都有几行。如果是这样,我建议在子查询中聚合:
select
o.order_id,
sa.shipping_name as user,
round(op.value - coalesce(od.value, 0), 2) order_total
from orders o
inner join (
select order_id, sum(price * amount) value
from order_products op
group by order_id
) op on op.order_id = o.order_id
left join (
select order_id, sum(discount) value
from order_discounts
group by order_id
) od on od.order_id = o.order_id
left join shipping_addresses sa
on o.shipping_address_id = sa.shipping_address_id
order by o.order_date desc, o.user_id desc
您还可以使用子查询:
select
o.order_id,
sa.shipping_name as user,
round(
(
select sum(op.price * op.amount)
from order_products op
where op.order_id = o.order_id
)
- (
select coalesce(sum(od.discount), 0)
from order_discounts od
where od.order_id = o.order_id
),
2
) order_total
from orders o
left join shipping_addresses sa
on o.shipping_address_id = sa.shipping_address_id
order by o.order_date desc, o.user_id desc