Mysql Laravel 5中的复杂联接SQL查询

Mysql Laravel 5中的复杂联接SQL查询,mysql,laravel,laravel-5,Mysql,Laravel,Laravel 5,我需要加入三个表:产品、订单、项目、订单 显然,products表包含产品。当用户将产品添加到购物车时,它会在order_items表中创建订单和行项目。当用户付款时,它将支付的总额放入orders表中。因此,从库存中删除的采购产品仅包括附在订单上的产品和附在已标记为“已付款”的订单上的项目 我需要归还所有的产品,但也要计算一下库存中还有多少。products表包含一个名为initial_quantity的字段,它是我们开始使用的产品数量。如果该字段为空,则产品没有限制 这是我当前的查询,它可以

我需要加入三个表:产品、订单、项目、订单

显然,products表包含产品。当用户将产品添加到购物车时,它会在order_items表中创建订单和行项目。当用户付款时,它将支付的总额放入orders表中。因此,从库存中删除的采购产品仅包括附在订单上的产品和附在已标记为“已付款”的订单上的项目

我需要归还所有的产品,但也要计算一下库存中还有多少。products表包含一个名为initial_quantity的字段,它是我们开始使用的产品数量。如果该字段为空,则产品没有限制

这是我当前的查询,它可以很好地返回特定类型的所有产品:

$swims = Product::where('product_type_id', 1)
            ->whereDate('visible_date', '<=', Carbon::now())
            ->where('active', true)
            ->where(function ($query) {
                $query->where('end_date', '>=', Carbon::now())
                      ->orWhere('end_date', null);  
            })          
            ->get();
我可以运行另一个查询,查看每个产品的销售量:

select product_id, SUM(quantity) sold from `order_items` inner join `orders` on `order_items`.`order_id` = `orders`.`id` and `orders`.`paid` is not null group by `product_id`
此查询返回:

+------------+------+
| product_id | sold |
+------------+------+
|          1 |    5 |
|          7 |    3 |
|         11 |    1 |
|         12 |    1 |
+------------+------+
我要寻找的是一种结合这两个或类似查询的方法,这样我就可以得到我要寻找的所有产品,加上这些产品已经售出的数量,从而得到类似的结果:

+----+-------------+------------+------------+--------------+------------------+-----------------+--------+------+
| id | name        | base_price | end_date   | visible_date | initial_quantity | product_type_id | active | sold |
+----+-------------+------------+------------+--------------+------------------+-----------------+--------+------+
|  1 | membership  |      30.97 | NULL       | 2019-08-04   |             NULL |               1 |      1 |    5 |
| 12 | repellendus |     779.24 | 2027-03-16 | 1990-12-19   |             NULL |               1 |      1 |    1 |
| 16 | ducimus     |     708.33 | NULL       | 1999-03-24   |             NULL |               1 |      1 |    0 |
+----+-------------+------------+------------+--------------+------------------+-----------------+--------+------+
我想要一个查询,返回我正在搜索的所有产品以及剩余的产品数量。我尝试过连接、左连接、右连接、子查询连接和联合。拉威尔似乎没有外部连接,否则我也会尝试这些

我尝试过此查询和许多其他迭代,但总是出现语法错误:

select * from (`products` where `product_type_id` = 1 and date(`visible_date`) <= '2019-08-08 17:10:12' and `active` = 1 and (`end_date` >= '2019-08-08 17:10:12' or `end_date` is null)) x INNER JOIN (select product_id, SUM(quantity) sold from `order_items` inner join `orders` on `order_items`.`order_id` = `orders`.`id` and `orders`.`paid` is not null group by `product_id`) y ON x.id = y.product_id
……或者,更好

SELECT p.*
     , COALESCE(y.sold,0) sold
  FROM products p
  LEFT
  JOIN 
     ( SELECT product_id
            , SUM(quantity) sold 
         FROM order_items oi
         JOIN orders o
           ON o.id = oi.order_id 
          AND o.paid is not null 
        GROUP 
           BY product_id
     ) y 
    ON y.product_id = p.id
 WHERE p.product_type_id = 1 
   AND DATE(p.visible_date) <= '2019-08-08 17:10:12' 
   AND p.active = 1 
   AND (p.end_date >= '2019-08-08 17:10:12' OR p.end_date IS NULL) 

将leftJoin用作订单项目well@Strawberry,完成。我也试着做一把小提琴,但似乎一次只能坐一张桌子。@priosshrsth,做到了,没有变化。@草莓,虽然我很感激你提供的指导,但这是一个在紧迫时间内定制的解决方案。我已经将概要文件数据从users表中移出并移到了它自己的表中,并且我至少有一个pivot,所以我确实理解这个概念。该网站是活的,运行正常,我将继续致力于重构我的代码和规范化数据库。在这一点上,我真的只需要查询方面的帮助。@草莓,我想要所有符合参数的产品:从product_type_id=1和datevisible_date=2019-08-08或end_date为空的产品中选择*,以及这些产品中有多少已经售出,或者更准确地说,有多少仍在销售。
select * from (`products` where `product_type_id` = 1 and date(`visible_date`) <= '2019-08-08 17:10:12' and `active` = 1 and (`end_date` >= '2019-08-08 17:10:12' or `end_date` is null)) x INNER JOIN (select product_id, SUM(quantity) sold from `order_items` inner join `orders` on `order_items`.`order_id` = `orders`.`id` and `orders`.`paid` is not null group by `product_id`) y ON x.id = y.product_id
CREATE TABLE `products` (
  `id` bigint(20) UNSIGNED NOT NULL,
  `name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
  `base_price` double(5,2) NOT NULL,
  `end_date` date DEFAULT NULL,
  `visible_date` date DEFAULT NULL,
  `initial_quantity` smallint(5) UNSIGNED DEFAULT NULL,
  `product_type_id` int(10) UNSIGNED NOT NULL,
  `active` tinyint(3) UNSIGNED NOT NULL DEFAULT '1'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;


INSERT INTO `products` (`id`, `name`, `base_price`, `end_date`, `visible_date`, `initial_quantity`, `product_type_id`, `active`) VALUES
(1, 'membership', 30.97, NULL, '2019-08-04', NULL, 1, 1),
(2, 'delectus', 347.44, NULL, '1975-06-08', 45, 1, 0),
(3, 'aut', 283.36, '1981-05-30', '1973-08-18', NULL, 3, 0),
(4, 'adipisci', 984.00, '1986-01-04', '1989-03-29', NULL, 3, 0),
(5, 'voluptas', 310.55, '2012-05-04', '1992-11-16', 45, 2, 1),
(6, 'quia', 657.81, '1976-11-23', '1978-10-23', 57, 2, 0),
(7, 'delectus', 601.91, NULL, '1987-03-09', 53, 2, 1),
(8, 'consequatur', 723.25, '1994-09-24', '1985-01-23', 33, 1, 0),
(9, 'perferendis', 427.33, NULL, '1995-12-08', 51, 3, 1),
(10, 'id', 674.39, '1974-12-13', '2007-05-12', 41, 2, 0),
(11, 'maxime', 133.49, NULL, '1986-07-15', NULL, 2, 1),
(12, 'repellendus', 779.24, '2027-03-16', '1990-12-19', NULL, 1, 1),
(13, 'sit', 956.76, NULL, '1993-07-02', 39, 2, 0),
(14, 'molestiae', 425.16, NULL, '1981-03-25', NULL, 3, 1),
(15, 'omnis', 418.78, '1976-11-03', '2007-10-07', NULL, 3, 1),
(16, 'ducimus', 708.33, NULL, '1999-03-24', NULL, 1, 1),
(17, 'numquam', 328.26, '2011-09-19', '2001-10-07', NULL, 3, 1),
(18, 'est', 962.26, NULL, '1970-12-24', NULL, 1, 0),
(19, 'quis', 520.18, NULL, '1978-03-25', NULL, 3, 0),
(20, 'facere', 891.89, NULL, '1979-10-31', 36, 3, 0),
(21, 'voluptatem', 518.47, '1982-06-26', '1975-03-14', NULL, 1, 1);
COMMIT;

    CREATE TABLE `order_items` (
      `order_id` bigint(20) UNSIGNED NOT NULL,
      `product_id` bigint(20) UNSIGNED NOT NULL,
      `quantity` tinyint(3) UNSIGNED NOT NULL DEFAULT '1',
      `price` double(5,2) NOT NULL,
      `tax` double(5,2) NOT NULL,
      `buy_now` tinyint(3) UNSIGNED NOT NULL DEFAULT '1',
      `created_at` timestamp NULL DEFAULT NULL,
      `updated_at` timestamp NULL DEFAULT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

    INSERT INTO `order_items` (`order_id`, `product_id`, `quantity`, `price`, `tax`, `buy_now`, `created_at`, `updated_at`) VALUES
    (1, 1, 1, 30.97, 4.03, 1, '2019-08-04 11:35:26', '2019-08-04 11:35:26'),
    (1, 12, 1, 779.24, 654.56, 1, '2019-08-04 11:35:26', '2019-08-04 11:35:26'),
    (2, 1, 1, 30.97, 4.03, 1, '2019-08-04 11:56:16', '2019-08-04 11:56:16'),
    (3, 1, 1, 30.97, 4.03, 1, '2019-08-07 17:25:43', '2019-08-07 17:25:43'),
    (3, 7, 1, 601.91, 210.67, 1, '2019-08-07 17:25:43', '2019-08-07 17:25:43'),
    (4, 1, 1, 30.97, 4.03, 1, '2019-08-08 15:44:45', '2019-08-08 15:44:45'),
    (4, 7, 1, 601.91, 210.67, 1, '2019-08-08 15:44:45', '2019-08-08 15:44:45'),
    (5, 1, 1, 30.97, 4.03, 1, '2019-08-08 15:46:07', '2019-08-08 15:46:07'),
    (5, 11, 1, 133.49, 88.10, 1, '2019-08-08 15:46:07', '2019-08-08 15:46:07'),
    (6, 1, 1, 30.97, 4.03, 1, '2019-08-08 15:46:55', '2019-08-08 15:46:55'),
    (6, 16, 1, 708.33, 687.08, 1, '2019-08-08 15:46:55', '2019-08-08 15:46:55'),
    (7, 1, 1, 30.97, 4.03, 1, '2019-08-08 15:47:37', '2019-08-08 15:47:37'),
    (7, 7, 1, 601.91, 210.67, 1, '2019-08-08 15:47:37', '2019-08-08 15:47:37'),
    (8, 1, 1, 30.97, 4.03, 1, '2019-08-08 15:48:13', '2019-08-08 15:48:13'),
    (8, 11, 1, 133.49, 88.10, 1, '2019-08-08 15:48:13', '2019-08-08 15:48:13');

    CREATE TABLE `orders` (
      `id` bigint(20) UNSIGNED NOT NULL,
      `user_id` bigint(20) UNSIGNED NOT NULL,
      `subtotal` double(7,2) DEFAULT NULL,
      `tax` double(7,2) DEFAULT NULL,
      `paid` double(7,2) DEFAULT NULL,
      `transaction` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
      `created_at` timestamp NULL DEFAULT NULL,
      `updated_at` timestamp NULL DEFAULT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

    INSERT INTO `orders` (`id`, `user_id`, `subtotal`, `tax`, `paid`, `transaction`, `created_at`, `updated_at`) VALUES
    (1, 1, 810.21, 658.59, 12343.00, NULL, '2019-08-04 11:35:26', '2019-08-04 11:35:26'),
    (2, 1, 30.97, 4.03, NULL, NULL, '2019-08-04 11:56:16', '2019-08-04 11:56:16'),
    (3, 1, 632.88, 214.70, 847.58, NULL, '2019-08-05 17:25:43', '2019-08-07 17:25:43'),
    (4, 5, 632.88, 214.70, 847.58, NULL, '2019-08-08 15:44:45', '2019-08-08 15:44:45'),
    (5, 5, 164.46, 92.13, 256.59, NULL, '2019-08-08 15:46:07', '2019-08-08 15:46:07'),
    (6, 5, 739.30, 691.11, NULL, NULL, '2019-08-08 15:46:55', '2019-08-08 15:46:55'),
    (7, 10, 632.88, 214.70, 847.58, NULL, '2019-08-08 15:47:37', '2019-08-08 15:47:37'),
    (8, 10, 164.46, 92.13, NULL, NULL, '2019-08-08 15:48:13', '2019-08-08 15:48:13');
SELECT a.*
     , COALESCE(b.sold,0) sold
  FROM 
     ( SELECT * 
         FROM products p
        WHERE p.product_type_id = 1 
          AND DATE(p.visible_date) <= '2019-08-08 17:10:12' 
          AND p.active = 1 
          AND (p.end_date >= '2019-08-08 17:10:12' or p.end_date IS NULL)
     ) a
  LEFT
  JOIN   
     ( SELECT product_id
            , SUM(quantity) sold 
         FROM order_items oi
         JOIN orders o
           ON o.id = oi.order_id
          AND o.paid is not null 
        GROUP 
           BY product_id
     ) b
    ON b.product_id = a.id;
SELECT p.*
     , COALESCE(y.sold,0) sold
  FROM products p
  LEFT
  JOIN 
     ( SELECT product_id
            , SUM(quantity) sold 
         FROM order_items oi
         JOIN orders o
           ON o.id = oi.order_id 
          AND o.paid is not null 
        GROUP 
           BY product_id
     ) y 
    ON y.product_id = p.id
 WHERE p.product_type_id = 1 
   AND DATE(p.visible_date) <= '2019-08-08 17:10:12' 
   AND p.active = 1 
   AND (p.end_date >= '2019-08-08 17:10:12' OR p.end_date IS NULL)