Multiple Condition from 2 columns with different criteria - mysql

Need to Select rows from table where need to use 2 columns with different criteria
CREATE TABLE IF NOT EXISTS `spec_property` (
`sp_id` int(11) unsigned NOT NULL,
`spm_id` int(11) unsigned NOT NULL,
`spec_value` varchar(255) NOT NULL,
`spec_last_value` varchar(55) DEFAULT NULL,
`product_id` int(11) unsigned NOT NULL,
`spec_order_by` tinyint(2) unsigned DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=77 ;
ALTER TABLE `spec_property`
ADD PRIMARY KEY (`sp_id`), ADD KEY `product_id` (`product_id`), ADD KEY `spec_value` (`spec_value`);
ALTER TABLE `spec_property`
MODIFY `sp_id` int(11) unsigned NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=75;
INSERT INTO `spec_property` (`sp_id`, `spm_id`, `spec_value`, `spec_last_value`, `product_id`, `spec_order_by`) VALUES
(31, 23, 'Octa Core', NULL, 4, NULL),
(34, 26, '2048', 'MB', 4, NULL),
(35, 27, '8192', 'MB', 4, NULL),
(36, 28, '2048', 'MB', 4, NULL),
(69, 62, 'Android', NULL, 4, NULL),
(70, 63, '5', NULL, 4, NULL),
(71, 65, 'Yes', NULL, 4, NULL),
(72, 66, 'Yes', NULL, 4, NULL),
(73, 67, '32000', NULL, 4, NULL),
(74, 68, '25', 'fps', 4, NULL);
http://sqlfiddle.com/#!9/95329/13
SELECT distinct(product_id)
FROM `spec_property`
WHERE (spm_id = '62' AND spec_value IN ('Android' , 'Windows'))
AND (spm_id = '27' AND spec_value BETWEEN 4096 AND 131072 )
If I use the 'OR' condition I can get this result:
( http://sqlfiddle.com/#!9/95329/1 ). Actually i need to find product id's which are matches the filter options like
SELECT DISTINCT (product_id)
FROM spec_property
WHERE spm_id_62 IN ('Android', 'Windows')
AND spm_id_27 BETWEEN 4096 AND 131072
AND spm_id_26 BETWEEN 4096 AND 131072

You could try another set of parenthesis to structure the query
SELECT distinct(product_id)
FROM `spec_property`
WHERE ((spm_id = '62' AND spec_value IN ('Android' , 'Windows'))
OR (spm_id = '27' AND spec_value BETWEEN 4096 AND 131072 )
OR (spm_id = '26' AND spec_value BETWEEN 4096 AND 131072 ))

Related

Nested mysql query over 3 tables does not show the correct result

I have a problem with a nested query.
There are 3 tables
gutschriften_products, orders_products , products
Query
CREATE TABLE IF NOT EXISTS `gutschriften_products` (
`gut_orders_products_id` int(11) NOT NULL AUTO_INCREMENT,
`gut_id` int(11) NOT NULL DEFAULT '0',
`orders_products_id` int(11) NOT NULL DEFAULT '0',
`orders_id` int(11) NOT NULL DEFAULT '0',
`products_id` int(11) NOT NULL DEFAULT '0',
`products_name` varchar(64) DEFAULT NULL,
`products_price` decimal(15,4) NOT NULL DEFAULT '0.0000',
`final_price` decimal(15,4) NOT NULL DEFAULT '0.0000',
`products_quantity` int(2) NOT NULL DEFAULT '0',
PRIMARY KEY (`gut_orders_products_id`)
) ;
INSERT INTO `gutschriften_products` (`gut_orders_products_id`, `gut_id`, `orders_products_id`, `orders_id`, `products_id`, `products_name`, `products_price`, `final_price`, `products_quantity`) VALUES
(1, 1, 12, 108, 375, 'Prod 375', '92.3529', '92.3529', 1),
(2, 2, 13, 109, 375, 'Prod 375', '65.9664', '65.9664', 1),
(3, 3, 51, 110, 377, 'Prod 377', '71.8487', '71.8487', 1),
(4, 4, 40, 111, 432, 'Prod 432', '82.7731', '82.7731', 1),
(5, 4, 41, 112, 427, 'Prod 427', '72.6891', '72.6891', 1),
(6, 4, 42, 113, 420, 'Prod 420', '72.6891', '72.6891', 1),
(7, 4, 43, 114, 423, 'Prod 423', '82.7731', '82.7731', 1),
(8, 4, 44, 115, 423, 'Prod 423', '82.7731', '82.7731', 1),
(9, 5, 59, 116, 451, 'Prod 451', '78.5714', '78.5714', 1);
====
CREATE TABLE IF NOT EXISTS `orders_products` (
`orders_products_id` int(11) NOT NULL AUTO_INCREMENT,
`orders_id` int(11) NOT NULL DEFAULT '0',
`products_id` int(11) NOT NULL DEFAULT '0',
`products_name` varchar(64) DEFAULT NULL,
`products_price` decimal(15,4) NOT NULL DEFAULT '0.0000',
`final_price` decimal(15,4) NOT NULL DEFAULT '0.0000',
`products_quantity` int(2) NOT NULL DEFAULT '0',
PRIMARY KEY (`orders_products_id`),
KEY `orders_id` (`orders_id`),
KEY `orders_id_2` (`orders_id`),
KEY `products_id` (`products_id`)
);
INSERT INTO `orders_products` (`orders_products_id`, `orders_id`, `products_id`, `products_name`, `products_price`, `final_price`, `products_quantity`) VALUES
(12, 108, 375, 'Prod 375', '100.7563', '100.7563', 1),
(13, 109, 375, 'Prod 375', '78.5714', '78.5714', 1),
(14, 110, 376, 'Prod 376', '70.1681', '70.1681', 1),
(15, 111, 377, 'Prod 377', '63.0252', '63.0252', 1),
(16, 112, 376, 'Prod 376', '70.1681', '70.1681', 1),
(17, 113, 377, 'Prod 377', '92.3529', '92.3529', 1),
(18, 114, 375, 'Prod 375', '69.3277', '69.3277', 1),
(19, 115, 376, 'Prod 376', '117.5600', '117.5600', 1),
(20, 116, 377, 'Prod 377', '79.8319', '79.8319', 1);
====
CREATE TABLE IF NOT EXISTS `products` (
`products_id` int(11) NOT NULL AUTO_INCREMENT,
`products_quantity` int(4) NOT NULL DEFAULT '0',
`products_price` decimal(15,8) NOT NULL DEFAULT '0.00000000',
`products_date_added` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`products_status` tinyint(1) NOT NULL DEFAULT '0',
`manufacturers_id` int(11) DEFAULT NULL,
`products_ordered` int(11) NOT NULL DEFAULT '0',
`products_ek` double(15,8) NOT NULL DEFAULT '0.00000000',
`products_verfuegbar` int(2) NOT NULL DEFAULT '1',
`products_geprueft` datetime NOT NULL,
`products_lagernd` int(4) NOT NULL,
PRIMARY KEY (`products_id`),
KEY `idx_products_date_added` (`products_date_added`)
) ;
INSERT INTO `products` (`products_id`, `products_quantity`, `products_price`, `products_date_added`, `products_status`, `manufacturers_id`, `products_ordered`, `products_ek`, `products_verfuegbar`, `products_geprueft`, `products_lagernd`) VALUES
(375, 18, '71.00840336', '2015-05-04 17:44:45', 1, 16, 75, 41.00000000, 1, '0000-00-00 00:00:00', 0),
(376, 10, '77.73109244', '2015-05-05 10:28:31', 1, 16, 67, 45.00000000, 1, '0000-00-00 00:00:00', 0),
(377, 10, '71.00840336', '2015-05-05 10:45:08', 1, 16, 52, 41.00000000, 1, '0000-00-00 00:00:00', 0),
(378, 8, '71.00840336', '2015-05-05 10:52:20', 1, 16, 35, 41.00000000, 1, '0000-00-00 00:00:00', 0),
(379, 10, '77.73109244', '2015-05-05 10:56:47', 1, 16, 36, 45.00000000, 1, '0000-00-00 00:00:00', 0);
I want to find out which items are sold / returned how often. Unfortunately, my approach only prints those items that have been sold AND returned. Items that have NEVER been sold or returned will not be displayed.
SELECT
(verkauft - gutschrift)*(P.products_price - products_ek) / (DATEDIFF(CURDATE(), P.products_date_added))*365 AS GEZE,
DATEDIFF(CURDATE(), P.products_date_added) AS dtage,
products_quantity,
DATE_FORMAT(P.products_date_added, " % d. % m. % Y") AS hinzu,
P.products_date_added,
A.products_id,
A.products_name,
verkauft,
gutschrift,
final_price,
verkauft - gutschrift AS summe,
gutschrift / verkauft*100 AS rquote,
products_ek AS EK,
P.products_price AS VK,
P.products_date_added AS aufgenommen,
P.manufacturers_id,
(
verkauft - gutschrift
)
*(P.products_price - products_ek) AS gewinn,
products_lagernd
FROM
(
select
products_id,
products_name,
sum(products_quantity) as verkauft
from
orders_products
where
orders_id BETWEEN 1 AND 11847
group by
products_id
)
AS A
JOIN
(
select
final_price,
products_id,
products_name,
sum(products_quantity) as gutschrift
from
gutschriften_products
where
final_price > 0
AND orders_id BETWEEN 1 AND 11847
group by
products_id
)
AS B
ON A.products_id = B.products_id
JOIN
(
select
products_geprueft,
products_id,
products_status,
manufacturers_id,
products_quantity,
products_ek,
products_price,
products_lagernd,
products_date_added
from
products
)
AS P
ON P.products_id = B.products_id
where
products_status > 0
AND 1 = 1
order by
products_name ASC,
products_id
Result:
There are only two rows with product_id = 375 and 377
But I have 3 other products 376, 378, 379
Why aren't they listed?
I know I shouldn't do this but I'm a bit board so.... (please compare it to your original sql and reach conclusions)
SELECT
(verkauft - gutschrift)*(P.products_price - products_ek) / (DATEDIFF(CURDATE(), P.products_date_added))*365 AS GEZE,
DATEDIFF(CURDATE(), P.products_date_added) AS dtage,
P.products_quantity,
DATE_FORMAT(P.products_date_added, "%d.%m.%Y") AS hinzu,
P.products_date_added,
P.products_id,
A.products_name,
verkauft,
gutschrift,
final_price,
verkauft - gutschrift AS summe,
gutschrift / verkauft*100 AS rquote,
products_ek AS EK,
P.products_price AS VK,
P.products_date_added AS aufgenommen,
P.manufacturers_id,
(verkauft - gutschrift ) *(P.products_price - products_ek) AS gewinn,
products_lagernd
FROM products P
LEFT JOIN ( select
products_id,
products_name,
sum(products_quantity) as verkauft
from orders_products
where orders_id BETWEEN 1 AND 11847
group by products_id ) AS A ON P.products_id = A.products_id
LEFT JOIN (select
final_price,
products_id,
products_name,
sum(products_quantity) as gutschrift
from gutschriften_products
where final_price > 0 AND orders_id BETWEEN 1 AND 11847
group by products_id ) AS B ON A.products_id = B.products_id
where products_status > 0
order by products_name ASC, products_id;
please reply if it's good for you...

MySql. 'group by' by parts

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?

MySQL not returning any result from my select query

I have the following multiple fields where I want to show statement of my expense and income. I am making a query to return description, credit, debit and balance from the MySQL query. SQL Fiddle
CREATE TABLE IF NOT EXISTS `trans` (
`ID` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`debit` decimal(15,4) NOT NULL,
`credit` decimal(15,4) NOT NULL,
`catid` smallint(5) NOT NULL,
`incomeid` bigint(20) unsigned NOT NULL DEFAULT '0',
`expenseid` bigint(20) unsigned NOT NULL DEFAULT '0',
`bankid` int(3) unsigned NOT NULL,
`date` date NOT NULL,
`updated_last` datetime NOT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=11 ;
--
-- Dumping data for table `trans`
--
INSERT INTO `trans` (`ID`, `debit`, `credit`, `catid`, `incomeid`, `expenseid`, `bankid`, `date`, `updated_last`) VALUES
(1, 0.0000, 2078.1000, 23, 1, 0, 2, '2015-04-01', '2015-04-30 14:16:37'),
(2, 0.0000, 2052.8200, 23, 2, 0, 2, '2015-04-02', '2015-04-30 14:17:23'),
(3, 0.0000, 4906.6200, 23, 3, 0, 2, '2015-04-02', '2015-04-30 14:17:06'),
(4, 0.0000, 12360.0500, 23, 4, 0, 1, '2015-04-02', '2015-04-30 12:18:15'),
(5, 0.0000, 10750.0000, 23, 5, 0, 2, '2015-04-03', '2015-04-30 12:25:31'),
(6, 0.0000, 2247.2000, 23, 6, 0, 1, '2015-04-03', '2015-04-30 12:29:45'),
(7, 0.0000, 4775.3000, 23, 7, 0, 2, '2015-04-04', '2015-04-30 12:37:40'),
(8, 0.0000, 2052.8200, 23, 8, 0, 2, '2015-04-04', '2015-04-30 14:16:05'),
(9, 2280.9100, 2280.9100, 23, 0, 1, 2, '2015-04-06', '2015-04-30 14:17:51'),
(10, 0.0000, 25000.0000, 23, 0, 2, 2, '2015-04-04', '2015-04-30 13:46:03');
CREATE TABLE IF NOT EXISTS `expense` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`type` int(11) unsigned NOT NULL,
`date` date NOT NULL,
`itemdesc` varchar(255) NOT NULL,
`quantity` varchar(30) NOT NULL,
`price` decimal(15,4) NOT NULL,
`grandtotal` decimal(15,4) NOT NULL,
`updated_last` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=11 ;
--
-- Dumping data for table `expense`
--
INSERT INTO `expense` (`id`, `type`, `date`, `itemdesc`, `quantity`, `price`, `grandtotal`, `updated_last`) VALUES
(1, 30, '2015-04-04', 'INT-CITY CASH DEP CHG INC ST-EC 300315', '1', 50.0000, 56.1800, '2015-05-01 02:35:37'),
(2, 30, '2015-04-04', 'IMPS P2P 562 508513121760#26-03- 300315', '1', 5.0000, 5.6200, '2015-05-01 02:37:18'),
(3, 29, '2015-04-08', 'mobile 1 Bill', '1', 599.0000, 673.0400, '2015-05-01 02:47:01'),
(4, 29, '2015-04-08', 'mobile 2 Bill Mar 2015', '1', 627.0000, 704.5000, '2015-05-01 02:58:08'),
(5, 38, '2015-04-10', 'staff 1 Salary Mar 2015', '1', 22000.0000, 22000.0000, '2015-05-01 03:02:21'),
(6, 38, '2015-04-10', 'staff 2 Salary Mar 2015', '1', 22000.0000, 22000.0000, '2015-05-01 03:03:40'),
(7, 29, '2015-04-11', 'landline 2 March 2015', '1', 388.9000, 436.9700, '2015-05-01 04:13:24'),
(8, 29, '2015-04-11', 'landline Mar 2015', '1', 605.2300, 680.0400, '2015-05-01 04:20:52'),
(9, 29, '2015-04-11', 'pager bill Mar 2015', '1', 591.4000, 664.5000, '2015-05-01 04:23:28'),
(10, 29, '2015-04-11', 'phone bill Mar 2015', '1', 198.7500, 223.3200, '2015-05-01 04:26:01');
CREATE TABLE IF NOT EXISTS `items` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`description` varchar(200) NOT NULL,
`catid` int(5) unsigned NOT NULL,
`status` tinyint(1) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=11 ;
--
-- Dumping data for table `items`
--
INSERT INTO `items` (`id`, `description`, `catid`, `status`) VALUES
(1, 'product 10000', 23, 1),
(2, 'product 50000', 23, 1),
(3, 'product 100000', 23, 1),
(4, 'product 500000', 23, 1),
(5, 'product High 10000', 23, 1),
(6, 'product High 50000', 23, 1),
(7, 'product High 100000', 23, 1),
(8, 'product High 500000', 23, 1),
(9, 'product Normal 10000', 23, 1),
(10, 'product Normal 25000', 23, 1);
CREATE TABLE IF NOT EXISTS `income` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`type` smallint(5) unsigned NOT NULL,
`date` date NOT NULL,
`itemdesc` int(11) unsigned NOT NULL DEFAULT '0',
`quantity` varchar(30) NOT NULL,
`price` decimal(15,4) NOT NULL,
`grandtotal` decimal(15,4) NOT NULL,
`updated_last` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=11 ;
--
-- Dumping data for table `income`
--
INSERT INTO `income` (`id`, `type`, `date`, `itemdesc`, `quantity`, `price`, `grandtotal`, `updated_last`) VALUES
(1, 23, '2015-04-01', 18, '10000', 0.1800, 2078.1000, '2015-04-30 14:16:37'),
(2, 23, '2015-04-02', 18, '10000', 0.1800, 2052.8200, '2015-04-30 14:17:23'),
(3, 23, '2015-04-02', 10, '25000', 0.1700, 4906.6200, '2015-04-30 14:17:06'),
(4, 23, '2015-04-02', 12, '100000', 0.1100, 12360.0500, '2015-04-30 12:18:15'),
(5, 23, '2015-04-03', 12, '100000', 0.1075, 10750.0000, '2015-04-30 12:25:31'),
(6, 23, '2015-04-03', 14, '10000', 0.2000, 2247.2000, '2015-04-30 12:29:45'),
(7, 23, '2015-04-04', 10, '25000', 0.1700, 4775.3000, '2015-04-30 12:37:40'),
(8, 23, '2015-04-04', 9, '10000', 0.1800, 2052.8200, '2015-04-30 14:16:05'),
(9, 23, '2015-04-06', 14, '10000', 0.2000, 2280.9100, '2015-04-30 14:17:51'),
(10, 23, '2015-04-04', 53, '250000', 0.1000, 25000.0000, '2015-04-30 13:46:03');
MySQL query:
set #depos=0;
set #total=0;
SELECT A.`date` , A.`debit` , A.`credit` ,
if( A.`credit` >0, #depos := A.`credit`, #depos := #depos + A.`credit` - A.`debit` ) AS depos_bal,
#total := #total + A.`credit` - A.`debit` AS net_bal, C.`itemdesc`, D.`description`
FROM `trans` A, `income` B, `expense` C, `items` D
WHERE A.`expenseid` = C.`id`
AND A.`incomeid` = B.`id`
AND B.`itemdesc` = D.`id`
AND A.`bankid` = '2'
ORDER BY A.`date` ASC, A.`ID` ASC
My several queries are just not good enough to get through with it.
How do I use the query to get all rows like the following?
Date Description Debit Credit Balance
04-04-2015 Item 1 4,775.30 27,445.28
04-04-2015 Item 2 56.18 27,389.10
07-04-2015 Item 3 2,359.56 29,743.04
You have no matching values between your trans, income, and expense tables. So by ANDing "Where A.expenseid = C.id AND A.incomeid = B." will produce no results.
If you run these queries you will realize that:
select * from trans A inner join income B on A.incomeid = B.id;
select * from trans A inner join expense C on A.expenseid = C.id;
Instead of ANDing you should left join on your tables:
SELECT A.`date` , D.`description`, C.`itemdesc`, A.`debit` , A.`credit`,
if( A.`credit` > 0, #depos := A.`credit`, #depos := #depos + A.`credit` - A.`debit` ) AS depos_bal,
#total := #total + A.`credit` - A.`debit` AS net_bal
FROM `trans` A left join `income` B ON A.`incomeid` = B.`id` left join `expense` C on A.`expenseid` = C.`id` left join `items` D ON B.`itemdesc` = D.`id`
WHERE A.`bankid` = '2'
ORDER BY A.`date` ASC, A.`ID` ASc;

MySQL - Selecting rows who's id is not present as a foreign key in another table

In my rails app I have two tables - device_ports and circuits. My goal is to get a list of device_ports whose id is not being used in the physical_port_id column of the circuits table.
I have done something similar before on other tables but here my query only returns one row when it should return 23 rows - there are 24 device ports for this device and one is in use.
select id, name, device_id, multiuse
from device_ports
where (device_id = 6 and multiuse = 1)
or device_ports.id not in (select physical_port_id from circuits)
So this query gets all multiuse ports (so even if the id was referenced in the foreign key, this row should still be returned) and should also get all rows where the device_id is 6 but is not referenced in circuits but only the multiuse row is being returned.
The result from the query is
id | name | device_id | multiuse
------------------------------------
268 | test-1 | 6 | 1
I did try to create an sql fiddle but the build just seems to timeout.
CREATE TABLE `device_ports` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`device_id` int(11) DEFAULT NULL,
`name` tinytext,
`speed` tinytext,
`multiuse` tinyint(1) DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `id` (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=291 DEFAULT CHARSET=latin1;
INSERT INTO `device_ports` (`id`, `device_id`, `name`, `speed`, `multiuse`, `created_at`, `updated_at`)
*emphasized text*VALUES
(1, 1, 'Test Device Port', '100', 0, NULL, NULL),
(2, 1, 'Test Port 2', '300', 1, NULL, NULL),
(289, 6, 'test-22', '100', 0, NULL, NULL),
(290, 6, 'test-23', '100', 0, NULL, NULL),
(288, 6, 'test-21', '100', 0, NULL, NULL),
(287, 6, 'test-20', '100', 0, NULL, NULL),
(286, 6, 'test-19', '100', 0, NULL, NULL),
(284, 6, 'test-17', '100', 0, NULL, NULL),
(285, 6, 'test-18', '100', 0, NULL, NULL),
(283, 6, 'test-16', '100', 0, NULL, NULL),
(282, 6, 'test-15', '100', 0, NULL, NULL),
(281, 6, 'test-14', '100', 0, NULL, NULL),
(280, 6, 'test-13', '100', 0, NULL, NULL),
(279, 6, 'test-12', '100', 0, NULL, NULL),
(278, 6, 'test-11', '100', 0, NULL, NULL),
(277, 6, 'test-10', '100', 0, NULL, NULL),
(276, 6, 'test-9', '100', 0, NULL, NULL),
(275, 6, 'test-8', '100', 0, NULL, NULL),
(274, 6, 'test-7', '100', 0, NULL, NULL),
(273, 6, 'test-6', '100', 0, NULL, NULL),
(272, 6, 'test-5', '100', 0, NULL, NULL),
(271, 6, 'test-4', '100', 0, NULL, NULL),
(270, 6, 'test-3', '100', 0, NULL, NULL),
(269, 6, 'test-2', '100', 0, NULL, NULL),
(268, 6, 'test-1', '100', 1, NULL, NULL),
(267, 6, 'test-0', '100', 0, NULL, NULL);
CREATE TABLE `circuits` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`organisation_id` int(11) DEFAULT NULL,
`physical_port_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=248 DEFAULT CHARSET=latin1;
INSERT INTO `circuits` (`id`, `organisation_id`, `physical_port_id`)
VALUES (1, 125, 267);
You could try using a LEFT OUTER JOIN:
SELECT DISTINCT d.id, d.name, d.device_id, d.multiuse
FROM device_ports d
LEFT OUTER JOIN circuits c ON c.physical_port_id = d.id
WHERE
(c.physical_port_id IS NULL AND d.device_id = 6)
OR (d.multiuse = 1 AND d.device_id = 6)
ORDER BY d.id
There are several techniques for this query, take a look at What's the difference between NOT EXISTS vs. NOT IN vs. LEFT JOIN WHERE IS NULL?.
SELECT p.*
FROM device_ports p
LEFT
JOIN circuits c
ON c.physical_port_id = p.id
WHERE p.device_id = 6
AND multiuse = 1
AND c.id IS NULL;

CakePHP Subquery from SQL

CREATE TABLE IF NOT EXISTS `messages` (
`id` int(11) unsigned NOT NULL auto_increment,
`user_id` int(11) unsigned NOT NULL,
`node_id` int(11) unsigned NOT NULL,
`reciever_id` int(11) unsigned NOT NULL,
`created` datetime default NULL,
`modified` datetime default NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=9 ;
INSERT INTO `messages` (`id`, `user_id`, `node_id`, `reciever_id`, `created`, `modified`) VALUES
(1, 1, 1, 15, '2011-12-07 00:00:00', '2011-12-07 02:00:00'),
(2, 15, 1, 1, '2011-12-07 02:00:00', '2011-12-07 02:00:00'),
(3, 15, 2, 1, '2011-12-07 11:00:00', '2011-12-07 11:00:00'),
(4, 1, 2, 15, '2011-12-07 11:00:00', '2011-12-07 11:00:00'),
(5, 1, 3, 18, '2011-12-07 11:00:00', '2011-12-07 11:00:00'),
(6, 18, 3, 1, '2011-12-07 11:00:00', '2011-12-07 11:00:00'),
(7, 1, 4, 18, '2011-12-07 12:00:00', '2011-12-07 12:00:00'),
(8, 18, 4, 1, '2011-12-07 12:00:00', '2011-12-07 12:00:00');
CREATE TABLE IF NOT EXISTS `nodes` (
`id` int(11) unsigned NOT NULL auto_increment,
`message` text NOT NULL,
`author_id` int(11) unsigned NOT NULL,
`read` tinyint(1) default NULL,
`created` datetime default NULL,
`modified` datetime default NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ;
INSERT INTO `nodes` (`id`, `message`, `author_id`, `read`, `created`, `modified`) VALUES
(1, 'Hi! How are you ? dude wanna meet up this weekend ?', 1, 0, '2011-12-07 02:00:00', '2011-12-07 02:00:00'),
(2, 'Sure. wanna go to Mangalore Pearl to eat Neer Dosa..', 15, 0, '2011-12-07 11:00:00', '2011-12-07 11:00:00'),
(3, 'Hi How are u Buddy ? Long time no see...', 1, 0, '2011-12-07 11:00:00', '2011-12-07 11:00:00'),
(4, 'yeah. are you back in town ? i think we should meet up man. its been ages ....', 18, 0, '2011-12-07 12:00:00', '2011-12-07 12:00:00');
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) unsigned NOT NULL auto_increment,
`first_name` varchar(255) default NULL,
`last_name` varchar(255) default NULL,
`email` varchar(255) default NULL,
`password` varchar(40) default NULL,
`username` varchar(255) default NULL,
`birthday` date default NULL,
`gender` varchar(255) default NULL,
`city_id` int(11) unsigned NOT NULL,
`status` varchar(255) NOT NULL,
`created` datetime default NULL,
`modified` datetime default NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=21 ;
I am trying to create a subquery in Cake. but not sure how to start :(
This is the SQL i want to execute
SELECT *
FROM (
SELECT *
FROM messages AS msg
WHERE user_id =1
ORDER BY modified DESC
) AS latest_message
GROUP BY reciever_id
Is it better to use sub Queries or write SQL statement ?
I'm not really sure what the necessity for a subquery is here, wouldn't something like this do the trick?
$this->Message->find('all', array(
'conditions' => array('Message.user_id' => 1),
'order' => array('Message.modified' => 'DESC'),
'group' => array('Message.receiver_id')
));
This would retrieve all the messages from the user with id 1, ordered by date modified and grouped by receiver_id.
Since you are trying to group by the receiver, then why not alter the query to retrieve the receivers and then the messages that belong to each one? Below, I am assuming use of the containable behavior.
$this->Receiver->find('all', array(
'contain' => array(
'Message' => array(
'conditions' => array('Message.user_id' => 1),
'order' => array('Message.modified' => 'DESC'),
)
)
));
EDIT
I added this query to see if it helps based on your comment.
$this->Message->find(
'all',
array(
'conditions' => array('Message.user_id' => 1),
'fields' => array('Message.*', 'MAX(Message.modified) as max_mod'),
'group' => 'Message.receiver_id'
)
);