Trying to get result in single query however unable to get correct sum of order stock, it display sum twice if waste item exits.
Please see below query
SELECT DISTINCT cd.id,i.*,c.category_name, SUM(CASE WHEN s.stock_type = 'f' THEN s.stock END) AS instock, SUM(CASE WHEN s.stock_type = 'w' THEN s.stock END) AS weststock, SUM(cd.qty) AS orderstock, IF(SUM(CASE WHEN s.stock_type = 'f' THEN s.stock END) IS NULL,0, SUM(CASE WHEN s.stock_type = 'f' THEN s.stock END)) - IF(SUM(CASE WHEN s.stock_type = 'w' THEN s.stock END) IS NULL,0, SUM(CASE WHEN s.stock_type = 'w' THEN s.stock END)) - IF(SUM(cd.qty) IS NULL,0, SUM(cd.qty)) AS total
FROM item AS i
JOIN categories AS c ON i.category_id = c.id
LEFT JOIN stock AS s ON i.id=s.item_id
LEFT JOIN manage_godown AS mg ON mg.id = s.godown_id
LEFT JOIN cart_detail AS cd ON i.id=cd.item_id AND cd.cart_id IN (
SELECT ca.id
FROM cart AS ca
WHERE ca.status ='o')
WHERE mg.id=8
GROUP BY i.id
ORDER BY i.id DESC
Table Structure
----------------------
--
-- Table structure for table `admin`
--
CREATE TABLE IF NOT EXISTS `admin` (
`id` double NOT NULL AUTO_INCREMENT,
`email` varchar(255) NOT NULL,
`name` varchar(255) NOT NULL,
`mobile_no` varchar(50) NOT NULL,
`password` varchar(255) NOT NULL,
`status` enum('a','d') NOT NULL COMMENT 'a= active,d=deactive',
`type` enum('a','m') NOT NULL DEFAULT 'm',
`last_login` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`change_password_key` text NOT NULL,
`isAsigned` enum('y','n') NOT NULL DEFAULT 'n',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=12 ;
-- --------------------------------------------------------
--
-- Table structure for table `area`
--
CREATE TABLE IF NOT EXISTS `area` (
`id` double NOT NULL AUTO_INCREMENT,
`area_name` varchar(255) NOT NULL,
`area_status` enum('a','d') NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ;
-- --------------------------------------------------------
--
-- Table structure for table `cart`
--
CREATE TABLE IF NOT EXISTS `cart` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` double NOT NULL,
`date` datetime NOT NULL,
`status` enum('c','o') NOT NULL DEFAULT 'c',
`ship_status` enum('y','n') NOT NULL DEFAULT 'n',
`shiping_address` text NOT NULL,
`order_date` datetime NOT NULL,
`area_id` int(11) NOT NULL,
`user_name` varchar(255) NOT NULL,
`email` varchar(255) NOT NULL,
`contact_number` varchar(255) NOT NULL,
`address` text NOT NULL,
`shipping_name` varchar(255) NOT NULL,
`order_delivery_status` enum('p','d','c') NOT NULL COMMENT 'p=pending,d=deliverd,c=cancle',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=10 ;
-- --------------------------------------------------------
--
-- Table structure for table `cart_detail`
--
CREATE TABLE IF NOT EXISTS `cart_detail` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`cart_id` int(11) NOT NULL,
`item_id` int(11) NOT NULL,
`qty` double NOT NULL,
`amount` double NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=13 ;
-- --------------------------------------------------------
--
-- Table structure for table `categories`
--
CREATE TABLE IF NOT EXISTS `categories` (
`id` double NOT NULL AUTO_INCREMENT,
`category_name` varchar(255) NOT NULL,
`isDefault` enum('y','n') NOT NULL DEFAULT 'n',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;
-- --------------------------------------------------------
--
-- Table structure for table `item`
--
CREATE TABLE IF NOT EXISTS `item` (
`id` double NOT NULL AUTO_INCREMENT,
`category_id` double NOT NULL,
`item_name` varchar(255) NOT NULL,
`item_image` text NOT NULL,
`price` double NOT NULL,
`isPopular` enum('Y','N') NOT NULL,
`item_status` enum('a','d') NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=34 ;
-- --------------------------------------------------------
--
-- Table structure for table `manage_godown`
--
CREATE TABLE IF NOT EXISTS `manage_godown` (
`id` double NOT NULL AUTO_INCREMENT,
`godown_name` varchar(150) NOT NULL,
`address` text NOT NULL,
`contact_number` varchar(50) NOT NULL,
`contact_person` varchar(255) NOT NULL,
`area_id` text NOT NULL,
`user_id` varchar(100) NOT NULL,
`godown_status` enum('a','d') NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;
--
-- Dumping data for table `area`
--
INSERT INTO `area` (`id`, `area_name`, `area_status`) VALUES
(1, 'C.G. Road', 'a'),
(2, 'S.G. Highway', 'a'),
(3, 'Bopal', 'a'),
(4, 'New Wadaj', 'a'),
(5, 'Ranip', 'a'),
(6, 'Bapunagar', 'a'),
(7, 'Gurukul RD', 'a'),
(8, 'Ghatlodia', 'a'),
(9, 'Nehru Nagar', 'a'),
(10, 'Old Wadaj', 'a'),
(11, 'Paldi', 'a'),
(12, 'NaranPura', 'a'),
(13, 'Anand Nagar', 'd'),
(14, 'Shahpur', 'a');
--
-- Dumping data for table `cart`
--
INSERT INTO `cart` (`id`, `user_id`, `date`, `status`, `ship_status`, `shiping_address`, `order_date`, `area_id`, `user_name`, `email`, `contact_number`, `address`, `shipping_name`, `order_delivery_status`) VALUES
(1, 1, '2015-03-09 20:30:36', 'o', 'n', 'roam', '2015-03-09 21:14:45', 7, 'account1', 'account1#superrito.com', '123456', 'roam', 'account1', 'p'),
(2, 1425936687, '2015-03-09 21:31:27', 'c', 'n', '', '0000-00-00 00:00:00', 0, '', '', '', '', '', 'p'),
(3, 1426012764, '2015-03-10 18:39:24', 'c', 'n', '', '0000-00-00 00:00:00', 0, '', '', '', '', '', 'p');
--
-- Dumping data for table `cart_detail`
--
INSERT INTO `cart_detail` (`id`, `cart_id`, `item_id`, `qty`, `amount`) VALUES
(1, 1, 1, 3, 80),
(2, 2, 1, 0.25, 80),
(3, 3, 1, 0.5, 80),
(4, 3, 2, 0.25, 45);
--
-- Dumping data for table `categories`
--
INSERT INTO `categories` (`id`, `category_name`, `isDefault`) VALUES
(1, 'vegitables', 'y'),
(2, 'fruits', 'y');
--
-- Dumping data for table `item`
--
INSERT INTO `item` (`id`, `category_id`, `item_name`, `item_image`, `price`, `isPopular`, `item_status`) VALUES
(1, 1, 'Tomato', '210fc803a958749e7b2a55c32c744f13.png', 80, 'Y', 'a'),
(2, 1, 'Potato', 'c244be2eab10bc46465d5b36448ba68b.jpg', 45, 'N', 'a'),
(3, 2, 'Cabbige', '05423c579cc99709923273c5222c4661.jpg', 120, 'Y', 'a');
--
-- Dumping data for table `manage_godown`
--
INSERT INTO `manage_godown` (`id`, `godown_name`, `address`, `contact_number`, `contact_person`, `area_id`, `user_id`, `godown_status`) VALUES
(8, 'Gurukul', 'Gurukul RD', '12457894', 'Salim', '7', '16', 'a'),
(9, 'Godown2', 'Godown2', '123456798', 'Samln', '12', '17', 'a');
--
-- Dumping data for table `user`
--
INSERT INTO `user` (`id`, `email`, `user_name`, `address`, `shiping_address`, `mobile_no`, `password`, `isVeryfied`, `created_date`, `email_verification`, `change_password_key`, `area_id`, `pincode`, `user_status`) VALUES
(1, 'account1#superrito.com', 'account1', 'roam', 'roam', '123456', '4b111bc4e9e96cd1d18d0359fdb94629', 'n', '2015-03-09 08:53:00', '', '', 0, 0, 'a'),
(2, 'tripathi_hhh#yahoo.com', 'hitesh tripathi', '', '', '9033913397', 'e10adc3949ba59abbe56e057f20f883e', 'n', '2015-03-10 06:31:23', '17a962a2eee74445747a3e194da6c556', 'be45b6a9362c65217ec88821b648a67f', 0, 0, 'a');
I placed order of Tomato 3KG Only however i added wasted item 3 times so sum of above query gives result 12KG in orderstock
Using COALESCE instead of IF ... IS NULL makes it a lot more readable... I'm waiting on your answer to #EdwinKrause's question to help with the rest.
SELECT DISTINCT cd.id,i.*,c.category_name,
SUM(CASE WHEN s.stock_type = 'f' THEN s.stock END) AS instock,
SUM(CASE WHEN s.stock_type = 'w' THEN s.stock END) AS weststock,
SUM(cd.qty) AS orderstock,
COALESCE( SUM(CASE WHEN s.stock_type = 'f' THEN s.stock END), 0) -
COALESCE(SUM(CASE WHEN s.stock_type = 'w' THEN s.stock END), 0) -
COALESCE(SUM(cd.qty), 0) AS total
FROM item AS i
JOIN categories AS c ON i.category_id = c.id
LEFT JOIN stock AS s ON i.id=s.item_id
LEFT JOIN manage_godown AS mg ON mg.id = s.godown_id
LEFT JOIN cart_detail AS cd ON i.id=cd.item_id AND cd.cart_id IN (
SELECT ca.id
FROM cart AS ca
WHERE ca.status ='o')
WHERE mg.id=2
GROUP BY i.id
ORDER BY i.id DESC
I want to list users which have a particular event count but I'm confused on which approach to take.
This is the database table:
CREATE TABLE `event` (
`event_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`visitor_id` int(11) DEFAULT NULL,
`key` varchar(200) DEFAULT NULL,
`value` text,
`label` varchar(200) DEFAULT '',
`datetime` datetime DEFAULT NULL,
PRIMARY KEY (`event_id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
INSERT INTO `event` (`event_id`, `visitor_id`, `key`, `value`, `label`, `datetime`)
VALUES
(1, 1, 'LOGIN', NULL, '', NULL),
(2, 2, 'LOGIN', NULL, '', NULL),
(3, 1, 'VIEW_PAGE', 'HOTEL', '', NULL),
(4, 2, 'VIEW_PAGE', 'HOTEL', '', NULL),
(5, 1, 'PURCHASE_HOTEL', NULL, '', NULL);
CREATE TABLE `visitor` (
`visitor_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`datetime` datetime DEFAULT NULL,
PRIMARY KEY (`visitor_id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
INSERT INTO `visitor` (`visitor_id`, `datetime`)
VALUES
(1, NULL),
(2, NULL);
and this is my approach:
SELECT DISTINCT
t1.`visitor_id`
FROM
`visitor` t1
JOIN `event` t2 on t1.visitor_id = t2.visitor_id AND t2.`key` = 'LOGIN'
JOIN `event` t3 on t1.visitor_id = t3.visitor_id AND t3.`key` = 'VIEW_PAGE' AND t3.`value` = 'HOTEL'
WHERE ( SELECT COUNT(*) FROM `event` WHERE `event`.`key` = 'PURCHASE_HOTEL' ) > 0
this should only list visitor 1 but it does actually list visitor 2 too which does not have the PURCHASE_HOTEL event.
As you can imagine, there will be more "rules" like all the JOIN events for each particular case. Can we correct and improve this somehow?
BONUS:
What is the name of this approach?
I think this is a "set-within-sets" query. I like using aggregation with a having clause for this type of query. The following checks the three conditions you are looking for:
select visitor_id
from event e
group by visitor_id
having sum(e.key = 'LOGIN') > 0 and
sum(e.key = 'VIEW_PAGE' and e.value = 'HOTEL') > 0 and
sum(e.key = 'PURCHASE_HOTEL') > 0;
The first condition in the having clause counts the number of LOGIN records and is true when at least one is found. (If you want exactly one, change > 0 to = 0.)
The second condition checks the viewing of the hotel page.
The third counts the number of hotel purchases.
Between two dates I need to display "today result".
CREATE TABLE IF NOT EXISTS `maf_game_stats` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`userid` varchar(100) NOT NULL,
`sessionid` varchar(100) NOT NULL,
`gid` int(11) NOT NULL,
`qid` int(11) NOT NULL,
`result` varchar(50) NOT NULL,
`accesstime` datetime NOT NULL,
PRIMARY KEY (`id`)
);
INSERT INTO `maf_game_stats` (`id`, `userid`, `sessionid`, `gid`, `qid`, `result`, `accesstime`) VALUES
(1, 'FYEJHQWSHXMV263', '35sd797n57plmreb5ecssuhhh2', 1, 5, '0', '2013-03-30 13:34:03'),
(2, 'FYEJHQWSHXMV263', '35sd797n57plmreb5ecssuhhh2', 1, 1, '0', '2013-03-30 13:34:07'),
(3, 'FYEJHQWSHXMV263', '35sd797n57plmreb5ecssuhhh2', 1, 10, '1', '2013-03-30 13:34:12'),
(4, 'FYEJHQWSHXMV263', '35sd797n57plmreb5ecssuhhh2', 1, 2, '1', '2013-03-30 13:34:17'),
(5, 'FYEJHQWSHXMV263', '35sd797n57plmreb5ecssuhhh2', 1, 16, '1', '2013-03-30 13:34:23');
My query is:
SELECT a.gid, a.qid, SUM(a.result = 1) correct, SUM(a.result = 0) incorrect FROM maf_game_stats a
INNER JOIN
(
SELECT USERID, gid, QID, MIN(ACCESSTIME) min_date
FROM maf_game_stats
GROUP BY USERID, gid, qid
) b ON a.USERID = b.USERID AND
a.gid = b.gid AND
a.qid = b.qid AND
a.ACCESSTIME = b.min_date
WHERE a.gid ='1'
AND a.ACCESSTIME BETWEEN CAST('2013-03-29' AS DATETIME) AND CAST('2013-03-30' AS DATETIME)
GROUP BY a.gid, a.qid
If I understand your question correctly, I think you just need to filter by current date:
WHERE a.gid ='1'
AND DATE(a.ACCESSTIME) = CURDATE()
GROUP BY a.gid, a.qid;
or you can use this, that could be faster because is able to make use of an index:
WHERE a.gid ='1'
AND a.ACCESSTIME >= CURDATE() AND a.ACCESSTIME < CURDATE() + INTERVAL 1 DAY
GROUP BY a.gid, a.qid;
I have a table with the following structure:
CREATE TABLE IF NOT EXISTS `user_settings` (
`user_ID` smallint(6) unsigned NOT NULL,
`item` varchar(50) NOT NULL,
`value` text,
`app_ID` tinyint(4) NOT NULL DEFAULT '0',
KEY `user_ID` (`user_ID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
# With these data
INSERT INTO `user_settings` (`user_ID`, `item`, `value`, `app_ID`) VALUES
(3, 'statusTrainer_ID', '0', 0),
(3, 'enabledApp', '1', 0),
(3, 'enabled_office_ID', '1', 1),
(3, 'enabled_office_ID', '2', 1),
(4, 'statusTrainer_ID', '1', 0),
(1, 'enabledApp', '1', 0),
(1, 'salesCode_ID_add', '1', 1),
(1, 'salesCode_ID_add', '2', 1),
(1, 'salesCode_ID_add', '3', 1),
(1, 'salesCode_ID_add', '20', 1),
(1, 'salesCode_ID_process', '2', 1),
(1, 'salesCode_ID_process', '3', 1),
(1, 'salesCode_ID_process', '20', 1);
I would like to run this query for data filtering
SELECT `user_ID`
FROM (`user_settings`)
WHERE (
`item` = 'enabledApp'
AND
`value` IN ('1')
)
AND
(
`item` = 'statusTrainer_ID'
AND
`value` IN ('0')
)
I am expecting '3' as result but MYSQL returns an empty set. why?? thanks for answer.
UPDATED
I solved it by subquery
SELECT distinct `user_ID`
FROM (`user_settings`)
WHERE user_ID IN(
SELECT `user_ID`
FROM (`user_settings`)
WHERE (
item = 'enabledApp'
AND
value IN (1)
))
AND user_ID IN(SELECT `user_ID`
FROM (`user_settings`)
WHERE (
item = 'statusTrainer_ID'
AND
value IN (0)
))
Demo
but it's little complicated...is there some cleaner solution????
You need an or:
SELECT `user_ID`
FROM (`user_settings`)
WHERE ( `item` = 'enabledApp' AND `value` IN ('1') ) OR
( `item` = 'statusTrainer_ID' AND `value` IN ('0') )
It returned the empty set because item cannot be both "enabledApp" and "statusTrainer_ID".
Oh, you are trying to get user ids that have both. Do it this way:
SELECT `user_ID`
FROM `user_settings`
GROUP BY `user_ID`
HAVING max(case when `item` = 'enabledApp' AND `value` IN ('1') then 1 else 0 end) = 1 and
max(case when `item` = 'statusTrainer_ID' AND `value` IN ('0') then 1 else 0 end) = 1
Demo