Related
I have three tables that I need to join: products, orders_items, orders
The products table contains, obviously, the products. When a user adds a product to their cart, it creates an order and a line item in the order_items table. When the user pays, it puts the total paid into the orders table. Therefore, purchased products removed from inventory only include products that are attached to an order_item attached to an order that has been marked paid.
I need to return all the products, but also somehow calculate how many are left in inventory. The products table contains a field called "initial_quantity" which is how many of the product we started with. If that field is NULL, there's no limit on the product.
Here is my current query, which works just fine for returning all the products of a certain type:
$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();
Here is the SQL for that query:
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)
The above query returns three results:
+----+-------------+------------+------------+--------------+------------------+-----------------+--------+
| id | name | base_price | end_date | visible_date | initial_quantity | product_type_id | active |
+----+-------------+------------+------------+--------------+------------------+-----------------+--------+
| 1 | membership | 30.97 | NULL | 2019-08-04 | NULL | 1 | 1 |
| 12 | repellendus | 779.24 | 2027-03-16 | 1990-12-19 | NULL | 1 | 1 |
| 16 | ducimus | 708.33 | NULL | 1999-03-24 | NULL | 1 | 1 |
+----+-------------+------------+------------+--------------+------------------+-----------------+--------+
I can run another query to see how much of each product has been sold:
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`
This query returns:
+------------+------+
| product_id | sold |
+------------+------+
| 1 | 5 |
| 7 | 3 |
| 11 | 1 |
| 12 | 1 |
+------------+------+
What I'm looking for is a way to combine those two (or similar) queries so I get all the products I'm looking for, plus the quantity of those products that have been sold, to give me a result similar to this:
+----+-------------+------------+------------+--------------+------------------+-----------------+--------+------+
| 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 |
+----+-------------+------------+------------+--------------+------------------+-----------------+--------+------+
I would like a query that returns all products I'm searching for and also how many are remaining. I've tried join, leftJoin, rightJoin, subquery joins and unions. Laravel doesn't seem to have outer joins or I would have tried those too.
I have tried this query and many other iterations and I always get a syntax error:
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
Can anybody come up with the query I'm looking for? If not in Laravel then in raw SQL would be fine and I can use it as-is or try to Laravelize it.
Thank you in advance.
Here is my MRE:
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;
...or, better...
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)
there is a table
CREATE TABLE geography_schedule (
id int(10) UNSIGNED NOT NULL,
geography_address_id int(10) UNSIGNED NOT NULL,
geography_city_id int(10) UNSIGNED NOT NULL,
sort int(5) UNSIGNED NOT NULL DEFAULT '500',
site varchar(5) NOT NULL DEFAULT 'site',
group_id int(10) NOT NULL DEFAULT '0',
day int(10) NOT NULL DEFAULT '1',
all_day tinyint(2) NOT NULL DEFAULT '0',
freeday int(10) NOT NULL DEFAULT '0',
from varchar(5) NOT NULL DEFAULT '09:00',
to varchar(5) NOT NULL DEFAULT '18:00',
timestamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
timestamp_update timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO geography_schedule (from, to, geography_address_id, day_from, day_to, group_id) VALUES
('09:00', '18:00', 533, 1, 1, 1),
('09:00', '18:00', 533, 2, 2, 1),
('11:00', '17:00', 533, 3, 3, 1),
('11:00', '17:00', 533, 4, 4, 1),
('09:00', '18:00', 533, 5, 5, 1),
('10:00', '17:00', 533, 6, 6, 1),
('09:00', '18:00', 533, 7, 7, 1);
I have a mysql query from this table enter image description here
SELECT `from`,`to`, `geography_address_id`, MIN(`day`) as `day_from`
,MAX(`day`) as `day_to`,`group_id`
FROM `geography_schedule`
WHERE `geography_address_id` = 533
GROUP BY `from`,`to`
ORDER BY `geography_schedule`.`day` ASC
result:
I need to group by lines 9:00 - 18:00 to save days day_from & day_to in proper order.
Is it possible to use GROUP BY in such a way it will give the result like this?
My DB structure and details below
CREATE TABLE `tbldakmst` (
`inwardId` int(11) NOT NULL,
`dakType` int(3) DEFAULT NULL,
`dakMarkTo` int(4) DEFAULT NULL,
`letterNo` varchar(100) DEFAULT NULL,
`markDeptt` varchar(20) DEFAULT NULL,
`dakSenderName` varchar(256) DEFAULT NULL,
`subject` varchar(256) DEFAULT NULL,
`remarks` text,
`comments` text,
`handoverDate` datetime DEFAULT NULL,
`handoverTo` int(11) DEFAULT NULL,
`forwardedTo` int(11) DEFAULT NULL,
`forwardedOn` datetime DEFAULT NULL,
`forwardedFrom` int(11) DEFAULT NULL,
`status` enum('0','1','2','3','4','5') DEFAULT NULL COMMENT '0=>CREATED, 1=>MARK TO, 2 => FORWARD TO, 3=>INITIATED, 4=>INITIATED AND DISPOSED, 5=>DISPOSED',
`createdBy` int(11) DEFAULT NULL,
`createdOn` datetime DEFAULT CURRENT_TIMESTAMP,
`modifiedBy` int(11) DEFAULT NULL,
`modifiedOn` datetime DEFAULT NULL,
`fileInitiateBy` int(11) DEFAULT NULL,
`fileInitiatedOn` datetime DEFAULT NULL,
`disposedBy` int(11) DEFAULT NULL,
`disposedOn` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `tbldakmst` (`inwardId`, `dakType`, `dakMarkTo`, `letterNo`, `markDeptt`, `dakSenderName`, `subject`, `remarks`, `comments`, `handoverDate`, `handoverTo`, `forwardedTo`, `forwardedOn`, `forwardedFrom`, `status`, `createdBy`, `createdOn`, `modifiedBy`, `modifiedOn`, `fileInitiateBy`, `fileInitiatedOn`, `disposedBy`, `disposedOn`) VALUES
(1, 0, 3, 'letter 5634', 'Office Dak', 'dheeraj kumar nayak', 'My subject data is here', 'Remrks Datammm VBCBCBBBBB', 'disposed again', '1970-01-26 00:00:00', 3, 3, '2017-05-02 15:14:50', 2, '5', 2, '2017-05-01 17:40:32', 3, '2017-05-07 15:42:40', 3, '2017-05-07 14:07:35', 3, '2017-05-07 14:39:51'),
(2, 0, 4, 'letter no 787887', 'Office Dak', 'kAMLESH kUMAR', 'subj', 'Remarks data', 'MY COMMENTS', '2017-05-02 15:14:50', 4, 2, '2017-05-02 15:14:50', 2, '2', 0, '2017-05-02 11:13:00', 2, '2017-05-05 13:00:44', NULL, NULL, 2, NULL),
(3, 0, 2, 'letter 5634', 'Office Dak', 'dheeraj kumar nayak', 'Need operator credentiasl', 'file putted edited', 'gdfgfg', '1970-01-01 00:00:00', 2, 3, NULL, 2, '1', 2, '2017-05-03 11:03:49', 2, '2017-05-04 14:48:48', NULL, NULL, NULL, NULL),
(4, 0, 2, 'letter 567', 'Office Dak', 'Dheraj Kumar', 'operator activation request from CSC-SPV', 'Personal Visit by EA', 'Disposed Now', '2017-05-07 00:00:00', 2, 2, NULL, 3, '5', 3, '2017-05-07 15:46:06', 2, '2017-05-07 16:10:14', 2, '2017-05-07 16:09:17', 2, '2017-05-07 16:10:14'),
(5, 0, 3, 'letter no 5566rr', 'Office Dak', 'ranjeet vaghle', 'operator request', 'proceed', 'File issues resolved and file is diposed', '0000-00-00 00:00:00', 3, 2, NULL, 3, '4', 3, '2017-05-07 15:55:32', 2, '2017-05-07 16:06:58', 2, '2017-05-07 16:06:58', 2, '2017-05-07 16:06:58'),
(6, 0, 2, 'letter 5634', 'Office Dak', 'dheeraj kumar nayak', 'hjjh', 'hjkhj', NULL, '0000-00-00 00:00:00', 2, NULL, NULL, NULL, '1', 2, '2017-05-07 17:27:36', NULL, NULL, NULL, NULL, NULL, NULL),
(7, 0, 2, 'Letter Number -56788899', 'Office Dak', 'dheeraj kumar nayak', 'dsfs', 'fdsfdsf', 'initiated', '0000-00-00 00:00:00', 2, 2, NULL, 2, '3', 2, '2017-05-07 17:51:56', 2, '2017-05-07 17:52:54', 2, '2017-05-07 17:52:54', NULL, NULL);
ALTER TABLE `tbldakmst`
ADD PRIMARY KEY (`inwardId`);
ALTER TABLE `tbldakmst` MODIFY `inwardId` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=8;
I have tried:
SELECT
sum(CASE
WHEN status = '1' THEN 1
ELSE 0
END) AS 'pending',
sum(CASE
WHEN status = '3' THEN 1
ELSE 0
END) AS 'initiated',
sum(CASE
WHEN status = '4' OR status = '5' THEN 1
ELSE 0
END) AS 'disposed' FROM tbldakmst
Above Query Output Was :
pending initiated disposed
2 1 3
<!-- Note:Status(0,1) ==>Pending ,Status (3) ==>Initiated,Status(4,5)==>Disposed
column FileInitiatedBy => User Value which one has initiated file.
Column disposedBy=> User Value which one has disposed file.
Column dakmarkTo => User Value which one have pending file -->
But I want Result Like this
User | Pending | Initiated | Disposed |
------------------------------------------------------
User 2 | 1 | 1 | 2 |
------------------------------------------------------
User 3 | 2 | 3 | 4 |
------------------------------------------------------
SELECT u.name AS 'Name',
sum(CASE
WHEN tb.status in ('0','1') AND (u.id = tb.dakMarkTo OR u.id = tb.createdBy) THEN 1
ELSE 0
END) AS 'pending' ,
sum(CASE
WHEN tb.status in ('3') AND u.id = tb.fileInitiateBy THEN 1
ELSE 0
END) AS 'initiated',
sum(CASE
WHEN tb.status in ('4', '5') AND u.id = tb.disposedBy THEN 1
ELSE 0
END) AS 'disposed'
FROM
tbldakmst tb, user u
group by u.name
This is my SQL table and data. http://sqlfiddle.com/#!9/effe2
CREATE TABLE IF NOT EXISTS `CustomValue` (
`id` int(11) NOT NULL,
`customFieldId` int(11) NOT NULL,
`relatedId` int(11) NOT NULL,
`fieldValue` text COLLATE utf8_unicode_ci,
`createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=MyISAM AUTO_INCREMENT=8 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
INSERT INTO `CustomValue` (`id`, `customFieldId`, `relatedId`, `fieldValue`, `createdAt`) VALUES
(1, 10, 4031, NULL, '2015-11-05 04:25:00'),
(2, 14, 4031, 'adsas#das.sadsa', '2015-11-05 04:25:00'),
(3, 13, 4031, '456', '2015-11-05 04:25:00'),
(4, 16, 4031, '2015-11-09', '2015-11-05 04:25:00'),
(5, 9, 4031, '456', '2015-11-05 04:25:00'),
(6, 11, 4031, 'dsasda', '2015-11-05 04:25:00'),
(7, 15, 4031, '1', '2015-11-05 04:25:00');
Right now it is as,
id customFieldId relatedId fieldValue createdAt
1 10 4031 (null) November, 05 2015 04:25:00
2 14 4031 adsas#das.sadsa November, 05 2015 04:25:00
3 13 4031 456 November, 05 2015 04:25:00
4 16 4031 2015-11-09 November, 05 2015 04:25:00
5 9 4031 456 November, 05 2015 04:25:00
6 11 4031 dsasda November, 05 2015 04:25:00
7 15 4031 1 November, 05 2015 04:25:00
I need to group by relatedId and and get the final output as 1 row for each relatedId.
This is the reference table.
CREATE TABLE IF NOT EXISTS `CustomField` (
`id` int(11) NOT NULL,
`customTypeId` int(11) NOT NULL,
`fieldName` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`relatedTable` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`defaultValue` text COLLATE utf8_unicode_ci,
`sortOrder` int(11) NOT NULL DEFAULT '0',
`enabled` char(1) COLLATE utf8_unicode_ci DEFAULT '1',
`listItemTag` char(1) COLLATE utf8_unicode_ci DEFAULT NULL,
`required` char(1) COLLATE utf8_unicode_ci DEFAULT '0',
`onCreate` char(1) COLLATE utf8_unicode_ci DEFAULT '1',
`onEdit` char(1) COLLATE utf8_unicode_ci DEFAULT '1',
`onView` char(1) COLLATE utf8_unicode_ci DEFAULT '1',
`listValues` text COLLATE utf8_unicode_ci,
`label` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`htmlOptions` text COLLATE utf8_unicode_ci
) ENGINE=MyISAM AUTO_INCREMENT=17 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
INSERT INTO `CustomField` (`id`, `customTypeId`, `fieldName`, `relatedTable`, `defaultValue`, `sortOrder`, `enabled`, `listItemTag`, `required`, `onCreate`, `onEdit`, `onView`, `listValues`, `label`, `htmlOptions`) VALUES
(13, 1, 'HOMEEMAIL', 'people', '', 0, '1', NULL, '1', '1', '1', '1', NULL, 'Home Email', ''),
(9, 1, 'LANDPHONENO', 'people', '', 0, '1', NULL, '1', '1', '1', '1', NULL, 'Land Phone No', ''),
(10, 12, 'ABOUTME', 'people', '', 0, '1', NULL, '0', '1', '1', '1', NULL, 'About Me', ''),
(11, 3, 'PHONENUMBER2', 'people', '', 0, '1', NULL, '1', '1', '1', '1', NULL, 'Phone Number 2', ''),
(14, 3, 'ALTERNATEEMAIL', 'people', '', 0, '1', NULL, '1', '1', '1', '1', NULL, 'Alternate Email', ''),
(15, 11, 'SCHOOLING?', 'people', '', 0, '1', NULL, '1', '1', '1', '1', NULL, 'Schooling?', ''),
(16, 4, 'JOINDATE', 'people', '', 0, '1', NULL, '1', '1', '1', '1', NULL, 'Join Date', '');
The final output should be,
relatedId | Alternate Email | Home Email | Join Date | Land Phone No | Phone Number 2 | Schooling?
--------------------------------------------------------------------------------------------------
4031 | adsas#das.sadsa | 456 | 2015-11-09| 456 | dsasda | 1
relatedId | Alternate Email | Home Email | Join Date | Land Phone No | Phone Number 2 | Schooling? | Interest
--------------------------------------------------------------------------------------------------
4033 | adsas#das.sadsa | 456 | 2015-11-09| 456 | dsasda | 1 | Drawing
The output of phpmyadmin
What you need here is PIVOT rows into columns, MySQL however doesn't have a native pivot operator like SQL Server or Oracle for example. But you can use CASE expression with group by to do this like this:
SELECT
v.relatedId, v.CreatedAt,
MAX(IF(f.fieldName = 'ABOUTME', COALESCE(v.fieldValue, f.defaultValue) , NULL)) AS 'ABOUTME',
MAX(IF(f.fieldName = 'ALTERNATEEMAIL', COALESCE(v.fieldValue, f.defaultValue) , NULL)) AS 'ALTERNATEEMAIL',
MAX(IF(f.fieldName = 'HOMEEMAIL', COALESCE(v.fieldValue, f.defaultValue) , NULL)) AS 'HOMEEMAIL',
MAX(IF(f.fieldName = 'JOINDATE', COALESCE(v.fieldValue, f.defaultValue) , NULL)) AS 'JOINDATE',
MAX(IF(f.fieldName = 'LANDPHONENO', COALESCE(v.fieldValue, f.defaultValue) , NULL)) AS 'LANDPHONENO',
MAX(IF(f.fieldName = 'PHONENUMBER2', COALESCE(v.fieldValue, f.defaultValue) , NULL)) AS 'PHONENUMBER2',
MAX(IF(f.fieldName = 'SCHOOLING?', COALESCE(v.fieldValue, f.defaultValue) , NULL)) AS 'SCHOOLING?'
FROM customField AS f
INNER JOIN Customvalue AS v ON f.Id = v.customFieldId
GROUP BY v.relatedId, v.CreatedAt;
And to do it dynamically you have to do it with dynamic sql like this:
SET #Colvalues = NULL;
SET #sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT CONCAT('MAX(IF(f.fieldName = ''',
f.fieldName, ''', COALESCE(v.fieldValue, f.defaultValue) , NULL)) AS ', '''', f.fieldName , '''')
) INTO #Colvalues
FROM customField AS f
INNER JOIN Customvalue AS v ON f.Id = v.customFieldId;
SET #sql = CONCAT('SELECT
v.relatedId, v.CreatedAt, ', #Colvalues , '
FROM customField AS f
INNER JOIN Customvalue AS v ON f.Id = v.customFieldId
GROUP BY v.relatedId, v.CreatedAt;');
PREPARE stmt
FROM #sql;
EXECUTE stmt;
Note that:
If the field value is null it will set the value from the default value field, thats what COALESCE(v.fieldValue, f.defaultValue) do.
You can eliminate NULL values like in the field Aboutname case, by adding a WHERE v.fieldValue IS NOT NULL.
This will give you:
Fiddle Here:
http://sqlfiddle.com/#!2/2f85f4/1
I am trying to create an 'inventory demand' report essentially; what products were sold between X and Y and how much of them.
The closest I can get is this query, but this doesn't return the correct math.
Can someone please offer some guidance?
SELECT orders_products.op_products_name
, orders_products.op_products_id
, SUM(orders_products.op_products_qty) AS TotalSold
FROM orders_products
, orders
WHERE orders.orders_date_purchased
AND orders.orders_date_purchased BETWEEN '2012-11-05 00:00:00' AND '2012-11-10 00:00:00'
GROUP
BY orders_products.op_products_id
ORDER
BY TotalSold DESC
The schema is available here:
--
-- Table structure for table orders
CREATE TABLE IF NOT EXISTS orders (
orders_ID bigint(20) unsigned NOT NULL AUTO_INCREMENT,
orders_date_purchased timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
orders_delivery_name varchar(100) NOT NULL,
orders_delivery_company_name varchar(100) NOT NULL,
orders_delivery_address varchar(255) NOT NULL,
orders_delivery_city varchar(100) NOT NULL,
orders_delivery_state char(2) NOT NULL,
orders_delivery_zipcode char(5) NOT NULL,
orders_delivery_phone char(10) NOT NULL,
orders_delivery_email varchar(100) NOT NULL,
orders_billing_name varchar(120) DEFAULT NULL,
orders_billing_address varchar(255) DEFAULT NULL,
orders_billing_city varchar(100) DEFAULT NULL,
orders_billing_state char(2) DEFAULT NULL,
orders_billing_zipcode char(5) DEFAULT NULL,
orders_billing_phone char(10) DEFAULT NULL,
orders_billing_email varchar(100) DEFAULT NULL,
orders_users_ID bigint(20) NOT NULL,
orders_distributor_ID bigint(20) DEFAULT NULL,
orders_affiliate_ID bigint(20) DEFAULT NULL,
orders_sales_tax decimal(11,2) NOT NULL,
orders_discount_applied decimal(11,2) DEFAULT NULL,
orders_ip_address char(15) NOT NULL,
orders_shipping_method varchar(255) NOT NULL,
orders_payment_method int(10) unsigned NOT NULL,
orders_order_total decimal(11,2) NOT NULL,
orders_shipping_cost decimal(11,2) DEFAULT NULL,
orders_total_saved decimal(11,2) NOT NULL,
orders_placed_by bigint(20) NOT NULL,
notes blob,
orders_inv_status int(11) DEFAULT NULL,
orders_date_modified timestamp NULL DEFAULT NULL,
orders_process_status int(11) DEFAULT '1',
PRIMARY KEY (orders_ID)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=2379 ;
--
-- Dumping data for table orders
INSERT INTO orders (orders_ID, orders_date_purchased, orders_delivery_name, orders_delivery_company_name, orders_delivery_address, orders_delivery_city, orders_delivery_state, orders_delivery_zipcode, orders_delivery_phone, orders_delivery_email, orders_billing_name, orders_billing_address, orders_billing_city, orders_billing_state, orders_billing_zipcode, orders_billing_phone, orders_billing_email, orders_users_ID, orders_distributor_ID, orders_affiliate_ID, orders_sales_tax, orders_discount_applied, orders_ip_address, orders_shipping_method, orders_payment_method, orders_order_total, orders_shipping_cost, orders_total_saved, orders_placed_by, notes, orders_inv_status, orders_date_modified, orders_process_status) VALUES
(1, '2012-11-05 19:58:12', 'John Smith', '', '123 Manatee Street', 'Navarre', 'FL', '32566', '8508675309', 'email#email.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 83, NULL, NULL, 0.06, NULL, '00.000.000.00', 'in_person_delivery', 9, 61.59, 0.00, 0.00, 0, NULL, 8, NULL, 3),
(2, '2012-11-06 01:05:20', 'Judy Richards', '', '456 Devmor Ct', 'Navarre', 'FL', '32566', '8508675309', 'email#email.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 87, NULL, NULL, 0.06, NULL, '00.000.000.00', 'in_person_delivery', 9, 158.97, 0.00, 0.00, 0, NULL, 8, NULL, 3),
(4, '2012-11-08 04:32:23', 'John Smith', '', '123 Manatee Street', 'Navarre', 'FL', '32578', '8508675309', 'email#email.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 92, NULL, NULL, 0.06, NULL, '00.000.000.00', 'in_person_delivery', 9, 52.99, NULL, 0.00, 0, NULL, 8, '0000-00-00 00:00:00', 3),
(5, '2012-11-09 00:11:54', 'Adam Davis', '', '4307 D134 Legendary Dr.', 'Navarre', 'FL', '32541', '8508675309', 'email#email.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 89, 84, 0, 0.06, NULL, '00.000.000.00', 'in_person_delivery', 9, 160.51, 0.00, 0.00, 0, NULL, 8, NULL, 3),
(6, '2012-11-09 21:14:25', 'Judy Sterling', '', '2310 Lexington Lane', 'Navarre', 'FL', '32566', '8508675309', 'email#email.com', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 87, NULL, NULL, 0.06, NULL, '00.000.000.00', 'in_person_delivery', 9, 158.97, 0.00, 0.00, 0, NULL, 8, NULL, 3);
--
-- Table structure for table orders_products
CREATE TABLE IF NOT EXISTS orders_products (
orders_products_ID bigint(20) NOT NULL AUTO_INCREMENT,
op_order_id bigint(20) unsigned NOT NULL,
op_products_id bigint(20) unsigned NOT NULL,
op_products_mfr_part_number varchar(65) NOT NULL,
op_products_name varchar(15) NOT NULL,
op_products_qty bigint(10) unsigned NOT NULL,
PRIMARY KEY (orders_products_ID)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=5923 ;
--
-- Dumping data for table orders_products
INSERT INTO orders_products (orders_products_ID, op_order_id, op_products_id, op_products_mfr_part_number, op_products_name, op_products_qty) VALUES
(1, 1, 491, 'CWP8489A001BA', 'X25', 1),
(2, 2, 2134, 'Professional Fee', 'Professional Fe', 3),
(3, 3, 473, 'CWPDR360', 'DR-360', 1),
(4, 4, 2134, 'Professional Fee', 'Professional Fe', 1),
(5, 5, 362, 'CWPDR360', 'DR-360', 1);
--
-- Table structure for table products
CREATE TABLE IF NOT EXISTS products (
products_id bigint(20) NOT NULL AUTO_INCREMENT,
products_brand varchar(200) NOT NULL,
products_brand_type varchar(200) NOT NULL,
products_mfr_part_number varchar(65) NOT NULL,
products_common_name varchar(15) NOT NULL,
products_msrp decimal(11,2) NOT NULL,
products_price decimal(11,2) NOT NULL,
products_description varchar(255) NOT NULL,
products_weight decimal(11,2) NOT NULL DEFAULT '1.00',
products_length decimal(3,2) DEFAULT NULL,
products_width decimal(3,2) DEFAULT NULL,
products_height decimal(3,2) DEFAULT NULL,
products_tax_exempt int(11) DEFAULT NULL,
PRIMARY KEY (products_id)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=2558 ;
--
-- Dumping data for table products
INSERT INTO products (products_id, products_brand, products_brand_type, products_mfr_part_number, products_common_name, products_msrp, products_price, products_description, products_weight, products_length, products_width, products_height, products_tax_exempt) VALUES
(1, 'HP', 'Original', '92298A ', '98A', 132.99, 131.66, 'Genuine HP® LaserJet 98A Black Toner Cartridge (92298A) ', 4.20, 9.99, 6.14, 9.72, NULL),
(2, 'HP', 'Original', 'C3903A ', '03A', 112.99, 111.86, 'Genuine HP® LaserJet 03A Black Toner Cartridge (C3903A) ', 3.00, 9.99, 4.80, 7.72, NULL),
(3, 'HP', 'Original', 'C3906A ', '06A', 87.99, 87.11, 'Genuine HP® LaserJet 06A Black Toner Cartridge (C3906A)', 2.13, 9.99, 5.16, 6.50, NULL),
(4, 'HP', 'Original', 'C3909A', '09A', 254.99, 252.44, 'Genuine HP® LaserJet 09A Black Toner Cartridge (C3909A)', 3.31, 9.99, 4.72, 8.07, NULL),
(5, 'HP', 'Original', 'C4092A ', '92A', 75.99, 75.23, 'Genuine HP® LaserJet 92A Black Toner Cartridge (C4092A) ', 2.20, 9.99, 5.16, 6.50, NULL);
The major problem is that you need a join condition between orders_products and orders. You have a , which is equivalent to cross join. As a simple rule: never use commas in the from clause.
In addition, the where clause was awkwardly phrased. Here is a rewrite of your query that also uses table aliases for readability:
SELECT op.op_products_name, op.op_products_id, SUM(op.op_products_qty) AS TotalSold
FROM orders_products op JOIN
orders o
ON op.op_order_id = o.orders_id
WHERE o.orders_date_purchased BETWEEN '2012-11-05 00:00:00' AND '2012-11-10 00:00:00'
GROUP BY op.op_products_id
ORDER BY TotalSold DESC;