I am working with inventory data that tells me the current inventory level every minute and stores it in the DB.
I want to find each instance where item_count fell to 0, take that row with timestamp, and then join it to the next row where the item_count rose above 0. This will then tell me how long that product was out of stock.
I came up with the following, but it doesn't return anything.
SELECT `inventories`.* from `inventories` inner join
(SELECT id, item_count, pusher_id, created_at as in_stock_at
FROM inventories
GROUP BY pusher_id) inv2
ON `inventories`.`created_at` < `inv2`.`in_stock_at`
AND `inv2`.`item_count` > `inventories`.`item_count`
AND `inventories`.`pusher_id` = `inv2`.`pusher_id`
WHERE `inventories`.`item_count` <= 0
AND `inventories`.`product_id`=9
Structure::
CREATE TABLE IF NOT EXISTS `inventories` (
`id` int(10) unsigned NOT NULL,
`client_id` int(10) unsigned NOT NULL,
`pusher_id` int(10) unsigned NOT NULL,
`product_id` int(10) unsigned NOT NULL,
`reader_id` int(10) unsigned NOT NULL,
`tags_blocked` double(6,2) NOT NULL,
`item_count` double(6,2) NOT NULL,
`active` tinyint(1) NOT NULL DEFAULT '1',
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`deleted_at` timestamp NULL DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=2881 ;
Data::
INSERT INTO `inventories` (`id`, `client_id`, `pusher_id`, `product_id`, `reader_id`, `tags_blocked`, `item_count`, `active`, `created_at`, `updated_at`, `deleted_at`) VALUES
(1, 1, 1, 9, 1, 0.00, 0.00, 1, '2015-10-22 04:45:47', '2015-10-23 04:45:47', NULL),
(2, 1, 1, 9, 1, 0.00, 0.00, 1, '2015-10-22 04:55:47', '2015-10-23 04:45:47', NULL),
(3, 1, 1, 9, 1, 0.00, 0.00, 1, '2015-10-22 05:05:47', '2015-10-23 04:45:47', NULL),
...
(10, 1, 1, 9, 1, 0.00, 0.00, 1, '2015-10-22 06:15:47', '2015-10-23 04:45:47', NULL),
(11, 1, 1, 9, 1, 10.00, 10.00, 1, '2015-10-22 06:25:47', '2015-10-23 04:45:47', NULL),
(12, 1, 1, 9, 1, 9.00, 9.00, 1, '2015-10-22 06:35:47', '2015-10-23 04:45:47', NULL),
(13, 1, 1, 9, 1, 8.00, 8.00, 1, '2015-10-22 06:45:47', '2015-10-23 04:45:47', NULL),
Desired Result::
Given the data above, I want to join row with ID 1 and row with ID 11.
1. Search the table for the first row with item_count=0, find a row (with same product_id and pusher_id) that has item_count > 0 and created_at > firstRow.created_at. and join them together.
Then, find the next instance of this occurrence.
I hope that clarifies the question.
Translating into SQL isn't that hard, but performance might be bad. This will get you the timestamp when the product was back in stock:
SELECT inv.*,
( SELECT MIN(`inv2`.`in_stock_at`)
FROM inventories AS inv2
WHERE inv2.`product_id` = inv.`product_id` -- same product
AND inv2.`pusher_id` = `inv`.`pusher_id` -- same pusher
AND `inv2`.`created_at` > inv.`created_at` -- later timestamp
AND `inv2`.`item_count` > 0 -- in stock
) AS inStockAgain_at
from `inventories` AS inv
WHERE inv.`item_count` <= 0 -- out of stock
-- AND inv.`product_id`=9
Edit:
Removing consecutive rows with zero stock is more complicated:
SELECT inv.*, dt.inStockAgain_at
FROM inventories AS inv
JOIN
(
SELECT product_id, pusher_id,
MIN(created_at) AS min_created_at,
inStockAgain_at
FROM
(
SELECT product_id, pusher_id, created_at,
( SELECT MIN(inv2.created_at)
FROM inventories AS inv2
WHERE inv2.product_id = inv.product_id -- same product
AND inv2.pusher_id = inv.pusher_id -- same pusher
AND inv2.created_at > inv.created_at -- later timestamp
AND inv2.item_count > 0 -- in stock
) AS inStockAgain_at
FROM inventories AS inv
WHERE inv.item_count <= 0
) AS dt
GROUP BY product_id, pusher_id, inStockAgain_at
) AS dt
ON inv.product_id = dt.product_id
AND inv.pusher_id = dt.pusher_id
AND inv.created_at = dt.min_created_at
See fiddle
Related
I am not an expert in sql and I would want some help in getting percentage change for every contract_address.
What I want to achieve
Get the percentage change of price price in 7 days using created_at.
-- Adminer 4.8.1 MySQL 5.5.5-10.4.10-MariaDB dump
SET NAMES utf8;
SET time_zone = '+00:00';
SET foreign_key_checks = 0;
SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO';
DROP TABLE IF EXISTS `nft_market_trade`;
CREATE TABLE `nft_market_trade` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`contract_address` varchar(100) DEFAULT NULL,
`token_id` int(11) DEFAULT NULL,
`price` double DEFAULT NULL,
`amount` int(11) DEFAULT NULL,
`type` enum('F','A') DEFAULT NULL,
`from_address` varchar(100) DEFAULT NULL,
`to_address` varchar(100) DEFAULT NULL,
`block_number` mediumtext DEFAULT NULL,
`tx_hash` varchar(100) DEFAULT NULL,
`event` varchar(100) DEFAULT NULL,
`created_at` datetime DEFAULT current_timestamp(),
`updated_at` datetime DEFAULT current_timestamp(),
`timestamp` mediumtext DEFAULT NULL,
`fee_artist_portion` double DEFAULT NULL,
`fee_treasury_portion` double DEFAULT NULL,
`auction_id` mediumtext DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `nft_market_trade` (`id`, `contract_address`, `token_id`, `price`, `amount`, `type`, `from_address`, `to_address`, `block_number`, `tx_hash`, `event`, `created_at`, `updated_at`, `timestamp`, `fee_artist_portion`, `fee_treasury_portion`, `auction_id`) VALUES
(342, '0xeed69d5ac882bbecb7449fe31e916a3c69b3c27a', 3, 0.000003, 1, 'F', '0x68cb4d2da9323586c11d58cc3c22f96282319050', '0x4091320130802794fc301642b8d61d090e419477', '97325503', '0x0648cf42ae8683baedda860c0b64fa061abc06d3353f898d042e118fb8537b48', 'SOLD', '2022-08-27 06:14:54', '2022-07-27 06:14:54', '1658902087', 0.00000006, 0.00000006, NULL),
(343, '0xeed69d5ac882bbecb7449fe31e916a3c69b3c27a', 3, 0.000003, 1, 'F', '0x68cb4d2da9323586c11d58cc3c22f96282319050', '0xb7204b9862d2302d2109d38d548111c966ef78ee', '97322182', '0x83ae44b08d1be5060a1a7d0bd6b82878b2a08734adacc392afdf57f32dde8046', 'PLACE', '2022-08-27 06:14:56', '2022-07-27 06:14:56', '1658898762', 0, 0, NULL),
(344, '0xeed69d5ac882bbecb7449fe31e916a3c69b3c27a', 3, 3.5, 1, 'F', '0x4091320130802794fc301642b8d61d090e419477', '0xb7204b9862d2302d2109d38d548111c966ef78ee', '97326062', '0xf9ccc91d53f696594ab04e6782a30c83a6e11663e641acf2999ca5236df710ad', 'PLACE', '2022-08-27 06:17:42', '2022-07-27 06:17:42', '1658902646', 0, 0, NULL),
(345, '0xeed69d5ac882bbecb7449fe31e916a3c69b3c27a', 3, 3.5, 1, 'F', '0x4091320130802794fc301642b8d61d090e419477', '0x68cb4d2da9323586c11d58cc3c22f96282319050', '97326730', '0xab4db021609514cb50846baa08124667634b80902cb9d1f3bb9189239980d218', 'SOLD', '2022-08-27 06:28:54', '2022-07-27 06:28:54', '1658903314', 0.07, 0.07, NULL),
(346, '0xeed69d5ac882bbecb7449fe31e916a3c69b3c27a', 3, 3.5, 1, 'F', '0x68cb4d2da9323586c11d58cc3c22f96282319050', '0x2b08e3ca40d615606c5068db8b66f41f460da811', '97328265', '0xa252f96edb41a0c6c7c66d7316b40cf9101b629e6342f4043ffce9c1e9322b86', 'PLACE', '2022-08-27 06:54:15', '2022-07-27 06:54:15', '1658904850', 0, 0, NULL)
Here is what I have tried
SELECT a.contract_address, a.price, a.event, a.created_at, max(price) - min(price) / min(price) * 100 as percentchange
FROM `nft_market_trade` a
WHERE a.event = "SOLD"
AND created_at >= now() - interval 7 day
group by a.contract_address;
Problem with my implementation is the percentage is calculated before the where clause, i.e. I am getting the percentage change before applying where clause.
Here is sqlfiddle link to my query. http://sqlfiddle.com/#!9/40809f5d/8
I would appreciate some help
You can write a subquery within your percentage change calculation to achieve this then GROUP BY contract_address. Optionally, you can remove the ROUND function to get a more detailed value.
SELECT contract_address,
price,
event,
created_at,
round(price * 100 / (SELECT SUM(price)
FROM nft_market_trade
WHERE event = "SOLD"
AND created_at >= now() - interval 7 day
GROUP BY contract_address), 2)
as
percentchange
From nft_market_trade
WHERE event = "SOLD"
AND created_at >= now() - interval 7 day
GROUP BY contract_address
Output: 0%
See Fiddle.
I have to write a command that uses the following database:
CREATE TABLE `autori` (
`idAutor` mediumint(8) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
`numeAutor` varchar(255) NOT NULL
);
INSERT INTO `autori` (`idAutor`, `numeAutor`) VALUES
(1, 'Ion Creanga'),
(2, 'Walter Scott'),
(3, 'Mihai Eminescu'),
(4, 'George Bacovia'),
(5, 'William Shakespeare'),
(6, 'Agatha Christie'),
(7, 'Jules Verne');
CREATE TABLE `edituri` (
`idEditura` smallint(5) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
`numeEditura` varchar(255) NOT NULL
);
INSERT INTO `edituri` (`idEditura`, `numeEditura`) VALUES
(1, 'Litera'),
(2, 'CARTEA ROMANEASCA'),
(3, 'MONDORO'),
(4, 'RAO'),
(5, 'PENGUIN BOOKS'),
(6, 'Paralela 45'),
(7, 'CASA EDITORIALA DEMIURG PLUS');
CREATE TABLE `carti` (
`idCarte` int(10) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
`titluCarte` varchar(255) NOT NULL,
`idAutor` mediumint(8) UNSIGNED NOT NULL,
`nrPagini` smallint(5) UNSIGNED DEFAULT NULL,
`ISBN` varchar(17) NOT NULL,
`anPublicare` year(4) DEFAULT NULL,
`idEditura` smallint(5) UNSIGNED NOT NULL,
`stoc` smallint(5) UNSIGNED NOT NULL DEFAULT '0',
`refExterna` varchar(255) DEFAULT NULL,
UNIQUE KEY `isbnUnic` (`ISBN`),
FOREIGN KEY (`idAutor`) REFERENCES `autori` (`idAutor`) ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY (`idEditura`) REFERENCES `edituri` (`idEditura`) ON DELETE CASCADE ON UPDATE CASCADE
);
INSERT INTO `carti` (`idCarte`, `titluCarte`, `idAutor`, `nrPagini`, `ISBN`, `anPublicare`, `idEditura`, `stoc`, `refExterna`) VALUES
(1, 'Amintiri din copilarie', 1, 48, '978-9975-74-380-8', 2014, 1, 5, NULL),
(2, 'Steaua Sudului', 7, 239, '978-973-23-3185-9', 2017, 2, 2, NULL),
(3, 'Sarpele de mare', 7, 199, '978-973-23-3184-2', 2017, 2, 1, NULL),
(4, '20.000 de leghe sub mari', 7, 300, '978-606-695-008-4', 2014, 3, 9, NULL),
(5, 'Crima din Orient Express', 6, 247, '978-606-609-620-1', 2017, 4, 20, NULL),
(6, 'Poirot investigheaza', 6, 217, '978-606-609-277-7', 2012, 4, 1, NULL),
(7, 'Journey to the Centre of the Earth', 7, 254, '978-0-14-062425-0', 1994, 5, 15, NULL),
(8, 'Cele mai frumoase povesti si povestiri', 1, 211, '978-973-47-2074-3', 2015, 6, 64, NULL),
(9, 'Poezii', 3, 382, '978-606-8395-85-2', 2014, 3, 32, NULL),
(10, 'Hamlet', 5, 228, '978-973-152-006-3', 2007, 7, 13, NULL);
CREATE TABLE `tipuriUtilizatori` (
`idTipUtilizator` tinyint(3) UNSIGNED NOT NULL,
`numeTip` varchar(255) NOT NULL
);
INSERT INTO `tipuriUtilizatori` (`idTipUtilizator`, `numeTip`) VALUES
(1, 'Necunoscut'),
(2, 'Bibliotecar'),
(3, 'Student');
CREATE TABLE `utilizatori` (
`idUtilizator` int(10) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`numeUtilizator` varchar(255) NOT NULL,
`idTipUtilizator` tinyint(3) UNSIGNED NOT NULL
);
INSERT INTO `utilizatori` (`idUtilizator`, `numeUtilizator`, `idTipUtilizator`) VALUES
(1, 'Xulescu', 3),
(2, 'Ygrec', 3),
(3, 'Zet', 0),
(4, 'Q', 2);
CREATE TABLE `imprumuturi` (
`idUtilizator` int(10) UNSIGNED NOT NULL,
`idCarte` int(10) UNSIGNED NOT NULL,
UNIQUE (`idUtilizator`,`idCarte`),
FOREIGN KEY (`idUtilizator`) REFERENCES `utilizatori` (`idUtilizator`) ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY (`idCarte`) REFERENCES `carti` (`idCarte`) ON DELETE CASCADE ON UPDATE CASCADE
) ;
INSERT INTO `imprumuturi` (`idUtilizator`, `idCarte`) VALUES
(2, 3),
(3, 4),
(1, 5);
My command needs to return titluCarte, numeAutor, numeEditura, and also to subtract the rows of imprumuturi table from carti.stoc. I have managed to write this, but the subtracting doesn't return 162-3. What am I doing wrong?
SELECT titlucarte,
numeautor,
numeeditura,
stoc
FROM carti
JOIN autori
ON ( carti.idautor = autori.idautor )
JOIN edituri
ON ( carti.ideditura = edituri.ideditura )
UNION
SELECT '--------------------------------------',
'--------',
'--------',
'----'
UNION
SELECT 'total carti',
'--------',
'--------',
Sum(stoc)
FROM carti
UNION
SELECT '--------------------------------------',
'--------',
'--------',
'----'
UNION
SELECT 'carti disponibile',
'--------',
'--------',
Sum(carti.stoc) - (SELECT Count(*)
FROM imprumuturi)
FROM imprumuturi,
carti;
Every other things works well, my problem is with the subtraction from the end of the command.
If you want 159 change your last select query to below.
SELECT 'carti disponibile',
'--------',
'--------',
Sum(carti.stoc) - (SELECT Count(*) FROM imprumuturi)
FROM carti;
DEMO
The reason you get garbage value in the stoc column is because of the 14th line in your above code. Its expecting a number but you are changing the datatype to string and hence the garbage values.
Try changing ----- to a number like 0 for example and you should get the desired output
See below on sql fiddle
http://sqlfiddle.com/#!9/25e5a1/17
SELECT titlucarte,
numeautor,
numeeditura,
stoc
FROM carti
JOIN autori
ON ( carti.idautor = autori.idautor )
JOIN edituri
ON ( carti.ideditura = edituri.ideditura )
UNION
SELECT '--------------------------------------' as 'titlucarte',
'--------' as 'numeautor',
'--------' as 'numeeditura',
/*'----' as 'stoc' */ /*code removed*/
0 as stoc /* code added*/
UNION
SELECT 'total carti' as 'titlucarte',
'--------' as 'numeautor',
'--------' as 'numeeditura' ,
Sum(stoc) as 'stoc'
FROM carti
UNION
SELECT '--------------------------------------' as 'titlucarte',
'--------' as 'numeautor',
'--------' as 'numeeditura' ,
'----' as 'stoc'
UNION
SELECT 'carti disponibile' as 'titlucarte',
'--------' as 'numeautor',
'--------' as 'numeeditura' ,
Sum(carti.stoc) - (SELECT Count(*)
FROM imprumuturi) as 'stoc'
FROM /*imprumuturi,*/
carti;
I have a messaging system which has the tables "message" which just contains the "subject" then "message_user" which contains the message body, who sent it, who its for and whether its deleted / unread.
#Message Table
CREATE TABLE `message` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`subject` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;
INSERT INTO `message` (`id`, `subject`)
VALUES
(1, 'Test'),
(2, 'Test Again');
#Message User Table
CREATE TABLE `message_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`message_id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`interlocutor` int(11) DEFAULT NULL,
`body` text,
`folder` enum('inbox','sent') NOT NULL,
`starmark` tinyint(1) NOT NULL DEFAULT '0',
`unread` tinyint(1) NOT NULL DEFAULT '1',
`deleted` enum('none','trash','deleted') NOT NULL DEFAULT 'none',
`date` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1;
INSERT INTO `message_user` (`id`, `message_id`, `user_id`, `interlocutor`, `body`, `folder`, `starmark`, `unread`, `deleted`, `date`)
VALUES
(1, 1, 1, 2, 'Hi, how are you?', 'sent', 0, 1, 'none', '2018-10-23 09:36:02'),
(2, 1, 2, 1, 'Hi, how are you?', 'inbox', 0, 1, 'none', '2018-10-23 09:36:02'),
(3, 1, 2, 1, 'I am good thanks, you?', 'sent', 0, 1, 'none', '2018-10-23 09:46:02'),
(4, 1, 1, 2, 'I am good thanks, you?', 'inbox', 0, 1, 'none', '2018-10-23 09:46:02'),
(5, 2, 1, 3, 'Hi!', 'sent', 0, 1, 'none', '2018-10-23 09:50:22'),
(6, 2, 3, 1, 'Hi!', 'inbox', 0, 1, 'none', '2018-10-23 09:50:22');
I wrote the following query:
SELECT
*
FROM message m
JOIN message_user mu ON m.id = mu.message_id
WHERE mu.deleted = 'none'
AND mu.user_id = 1 #user_id of person checking messages
ORDER BY mu.id DESC;
But this is currently returning 3 rows even though there is only two conversations. I tried to GROUP BY but it still showed 3 rows.
I would expect the first two rows in the above example not the last one.
I want the query to return a list of the conversations with the latest message which has been sent which I (user_id) am involved in.
Since your MySQL version is 8.0+, we can utilize Window functions, such as Row_number(); otherwise the solution would have been much verbose, using Session variables.
For a partition (group) of m.id, we will determine the row number values. Row number values will be ordered in descending order of date.
Now, we simply need to use this result-set as a Derived Table, and just consider those rows where row number value is 1.
Date is a keyword in MySQL. You should avoid naming column/table using it. Still if you have to do so, you will need to use backticks around it.
Try the following (DB Fiddle DEMO):
SELECT dt.*
FROM (
SELECT m.id,
m.subject,
mu.id AS message_user_id,
mu.message_id,
mu.user_id,
mu.interlocutor,
mu.body,
mu.folder,
mu.starmark,
mu.unread,
mu.deleted,
mu.`date`,
Row_number()
OVER (PARTITION BY m.id
ORDER BY mu.`date` DESC) AS row_no
FROM message m
JOIN message_user mu
ON m.id = mu.message_id
WHERE mu.deleted = 'none'
AND mu.user_id = 1 ) AS dt
WHERE dt.row_no = 1
ORDER BY dt.id DESC
Try this :
select
m.id as id_message, m.subject as subject_message,
mu.id as id_message_user, mu.interlocutor, mu.body, mu.folder, mu.starmark, mu.deleted, mu.date
from message as m
inner join message_user as mu on mu.message_id = m.id and mu.deleted = 'none' and mu.user_id = 1
group by id_message
order by id_message_user desc
I removed
mu.user_id : it's in the inner join condition so always 'none'
mu.unread :same, always 1
mu.message_id : duplicate of id_message
http://sqlfiddle.com/#!9/91a5e4/15
I have a problem with my update query. I need to change notify_admin from 0 to 1 only for last users row if action_type = abuse. (Result should be rows with id=9 and id=13)
I'm trying something like that:
UPDATE user_log SET notify_admin = 1
WHERE id IN (
SELECT DISTINCT user_id FROM (SELECT user_id FROM user_log) as UNIKALNE
) AND action_type LIKE 'abuse'
Unfortunately it update only 1 row (id=3).
Here is my table:
CREATE TABLE IF NOT EXISTS `user_log` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`user_id` int(10) unsigned NOT NULL,
`action_type` enum('login','logout','abuse') CHARACTER SET latin1 NOT NULL,
`notify_admin` tinyint(1) NOT NULL DEFAULT '0',
`saved` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=15;
INSERT INTO `user_log` (`id`, `user_id`, `action_type`, `notify_admin`, `saved`) VALUES
(1, 1, 'login', 0, '2015-11-02 12:13:14'),
(2, 1, 'logout', 0, '2015-11-02 13:12:11'),
(3, 1, 'abuse', 0, '2016-01-03 14:10:02'),
(4, 2, 'abuse', 0, '2016-01-04 17:47:03'),
(5, 2, 'login', 0, '2016-01-04 18:11:55'),
(6, 1, 'abuse', 0, '2016-01-04 18:23:57'),
(7, 1, 'abuse', 0, '2016-01-04 18:24:23'),
(8, 2, 'logout', 0, '2016-01-04 18:25:24'),
(9, 1, 'abuse', 0, '2016-01-04 18:25:32'),
(10, 1, 'login', 0, '2016-01-05 21:02:59'),
(11, 3, 'login', 0, '2016-01-05 21:28:43'),
(12, 3, 'logout', 0, '2016-01-05 21:52:01'),
(13, 2, 'abuse', 0, '2016-01-05 22:00:35'),
(14, 1, 'logout', 0, '2016-01-05 22:12:09');
You need to first get the most recent saved value per user and then update the column.
UPDATE user_log
JOIN
(
select id from user_log JOIN (
select user_id,max(saved) max_saved
from user_log
where action_type="abuse"
group by user_id
) t
ON t.user_id = user_log.user_id AND t.max_saved = user_log.saved
) t2
ON user_log.id = t2.id
SET notify_admin = 1
Here you are checking User_id from table with distinct so it will give 1,2,3 only and then comparing with abuse action type so it will update row 3 which matches.
replace User_id with id if you want to update for all rows
UPDATE user_log SET notify_admin = 1 WHERE id IN (SELECT DISTINCT id FROM (SELECT id FROM user_log) as UNIKALNE) AND action_type LIKE 'abuse'
I wish to divide values from the same column using mySQL.
is there a better way of doing this??? Do I really need 3 select statements?
SELECT (SELECT FixAM From Fixes WHERE Id = 1) / (SELECT FixAM From Fixes WHERE Id = 2)
My table structure is as follows:
CREATE TABLE IF NOT EXISTS `Fixes` (
`Id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'PK',
`CurrencyId` int(11) NOT NULL COMMENT 'FK',
`MetalId` int(11) NOT NULL COMMENT 'FK',
`FixAM` decimal(10,5) NOT NULL,
`FixPM` decimal(10,5) DEFAULT NULL,
`TimeStamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`Id`),
KEY `CurrencyId` (`CurrencyId`),
KEY `MetalId` (`MetalId`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci AUTO_INCREMENT=13 ;
--
-- Dumping data for table `Fixes`
--
INSERT INTO `Fixes` (`Id`, `CurrencyId`, `MetalId`, `FixAM`, `FixPM`, `TimeStamp`) VALUES
(1, 1, 1, '1592.50000', '1586.25000', '2013-02-25 15:10:21'),
(2, 2, 1, '1051.84900', '1049.59300', '2013-02-25 15:10:21'),
(3, 3, 1, '1201.88700', '1194.10600', '2013-02-25 15:10:21'),
(4, 1, 2, '29.17000', NULL, '2013-02-25 13:54:02'),
(5, 2, 2, '19.27580', NULL, '2013-02-25 13:54:02'),
(6, 3, 2, '21.98190', NULL, '2013-02-25 13:54:02'),
(7, 1, 3, '1627.00000', '1620.00000', '2013-02-25 14:28:59'),
(8, 2, 3, '1074.65000', '1072.50000', '2013-02-25 14:28:59'),
(9, 3, 3, '1229.30000', '1218.95000', '2013-02-25 14:28:59'),
(10, 1, 4, '747.00000', '748.00000', '2013-02-25 14:28:59'),
(11, 2, 4, '493.40000', '495.20000', '2013-02-25 14:28:59'),
(12, 3, 4, '564.40000', '562.85000', '2013-02-25 14:28:59');
I think this is what you're looking for:
SELECT MetalId,
MAX(CASE WHEN CurrencyId = 1 THEN FixAM END) /
MAX(CASE WHEN CurrencyId = 2 THEN FixAM ELSE 1 END) Output
FROM Fixes
GROUP BY MetalId
This produces 1592.50000 / 1051.849000. If you want the opposite, swap the currency ids.
SQL Fiddle Demo
In case you don't have a CurrencyId = 2, I defaulted the dividing value to 1 so you wouldn't receive an error.