sum of values based on condition - mysql

Iam new to mysql
I have two tables,
CREATE TABLE `tab1` (
`tid1` int(2) NOT NULL auto_increment,
`payer` varchar(100) default NULL,
`receiver` varchar(100) default NULL,
`payAmt` decimal(20,2) default '0.00',
`recAmt` decimal(20,2) default '0.00',
PRIMARY KEY (`tid1`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;
--
-- Dumping data for table tab1
INSERT INTO `tab1` (`tid1`, `payer`, `receiver`, `payAmt`, `recAmt`) VALUES
(1, 'aaa', 'bbb', 100.00, -100.00),
(2, 'aaa', 'ccc', 200.00, -200.00),
(3, 'bbb', 'aaa', 150.00, -150.00),
(4, 'ccc', 'aaa', 175.00, -175.00);
--
-- Table structure for table tab2
CREATE TABLE `tab2` (
`tid2` int(2) NOT NULL auto_increment,
`payer` varchar(100) default NULL,
`receiver` varchar(100) default NULL,
`payAmt` decimal(20,2) default '0.00',
`recAmt` decimal(20,2) default '0.00',
PRIMARY KEY (`tid2`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;
--
-- Dumping data for table tab2
INSERT INTO `tab2` (`tid2`, `payer`, `receiver`, `payAmt`, `recAmt`) VALUES
(1, 'ddd', 'aaa', 223.00, -223.00),
(2, 'aaa', 'bbb', 429.00, -429.00),
(3, 'ccc', 'aaa', 102.00, -102.00);
I want the result as shown below
name payAmtTotal recAmtTotal payAmtTotal-recAmtTotal
aaa 729 650 79
bbb 150 529 -379
ccc 277 -277 554
ddd 223 0 223

Not sure why there is more then 1 table with this information, first thing that comes up is trying to turn this into 1 table.
Anyway, not sure if this is the best and cleanest way bu if the tables aren't to large and you have to option of creating temporary tables then here's one way of getting the desired results.
CREATE TEMPORARY TABLE IF NOT EXISTS temp1 AS (SELECT * FROM `tab1`);
INSERT INTO temp1 SELECT * FROM `tab2`;
CREATE TEMPORARY TABLE IF NOT EXISTS temp2 AS (SELECT * FROM `temp1`);
CREATE TEMPORARY TABLE IF NOT EXISTS temp3 AS (SELECT * FROM `temp1`);
SELECT
`payer` AS `name`,
(SELECT SUM(payAmt) AS `p` FROM temp2 AS t WHERE t.payer = temp1.payer) AS `payAmtTotal` ,
(SELECT SUM(payAmt) AS `r` FROM temp3 AS t WHERE t.receiver = temp1.payer) AS `recAmtTotal`
FROM
temp1
GROUP BY `name`;
Basically you create a singe (temporary) table and fill this table with the data from the two existing tables.
Since MySQL won't let you use the same temporary table more then once in a single query you need to create a few more :-) they can be copies of the first one though.
After that the selection query on itself isn't that complicated.

Related

adding foreign key from other table based on column values of first table - MySql

I am new to mysql
I have two Tables in my database.
id_details_table
CREATE TABLE `id_details_table` (
`ID` int(11) NOT NULL,
`CNIC` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
sample record
INSERT INTO `id_details_table` (`ID`, `CNIC`) VALUES
(1, '3230328119795'),
(2, '4200004873681'),
(3, '4230188867895'),
(4, '3740566124323'),
(5, '4220191179125');
mobiles_sim_details
> CREATE TABLE `mobiles_sim_details` (
`Mobile` double DEFAULT NULL,
> `CNIC` varchar(255) DEFAULT NULL, `id_cnic` int(11) DEFAULT NULL )
> ENGINE=InnoDB DEFAULT CHARSET=latin1;
sample Record for table
INSERT INTO `mobiles_sim_details` (`Mobile`, `CNIC`, `id_cnic`) VALUES
(3000651082, '3230328119795', 0),
(3040877459, '4200004873681', 0),
(3013329415, '4230188867895', 0),
(3028590340, '3740566124323', 0),
(3000720166, '4220191179125', 0);
2 columns CNIC are present in both tables
Now What I want is, where there is 0 in the 2nd table I want it to be auto filled with the relevant ID from table 1 based on the data of CNIC from 2nd table.
I have tried this query but it didn't worked
UPDATE `mobiles_sim_details` SET `id_cnic`='[value-3]' WHERE (SELECT id FROM id_details_table WHERE CNIC = mobiles_sim_details.CNIC);
How can i Acheive this ?
UPDATE mobiles_sim_details t1
JOIN id_details_table t2 USING (CNIC)
SET t1.id_cnic = t2.id

How to find count in many to many relationship in MySql, Cakephp 3.6

I need to calculate the count(vendors.id) for each category.
ie: how many vendors are there for each category(not sub-category)
I am using cakephp 3.6 framework and MySQL as database
I tried with all possible way that i knew but not found any solution. Can anybody help me, is very important for my project
[UPDATE]
sql query i have used:
SELECT cat.id,cat.name ,COUNT(`vendor_id`) AS vendor_count FROM `vendor_services` JOIN `categories` ON(`vendor_services`.`category_id` = `categories`.`id`) JOIN `categories` AS cat ON(categories.category_id = cat.id) WHERE 1 GROUP BY cat.id
[UPDATE]Bellow is the sql to create corresponding tables
-- phpMyAdmin SQL Dump
-- version 4.7.0
-- https://www.phpmyadmin.net/
--
-- Host: 127.0.0.1
-- Generation Time: Dec 04, 2018 at 10:50 AM
-- Server version: 10.1.24-MariaDB
-- PHP Version: 7.1.6
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET AUTOCOMMIT = 0;
START TRANSACTION;
SET time_zone = "+00:00";
--
-- Database: `demo123`
--
-- --------------------------------------------------------
--
-- Table structure for table `categories`
--
CREATE TABLE `categories` (
`id` int(11) NOT NULL,
`category_id` tinyint(4) NOT NULL,
`name` varchar(60) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--
-- Dumping data for table `categories`
--
INSERT INTO `categories` (`id`, `category_id`, `name`) VALUES
(1, 0, 'Books'),
(2, 0, 'Electronics'),
(3, 0, 'Garden'),
(4, 1, 'Novel'),
(5, 1, 'Science'),
(6, 1, 'Story'),
(7, 2, 'Mobile'),
(8, 2, 'Tablet'),
(9, 2, 'Headphone'),
(10, 3, 'Pumps'),
(11, 3, 'Pipes');
-- --------------------------------------------------------
--
-- Table structure for table `vendors`
--
CREATE TABLE `vendors` (
`id` int(11) NOT NULL,
`name` varchar(60) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--
-- Dumping data for table `vendors`
--
INSERT INTO `vendors` (`id`, `name`) VALUES
(1, 'VR Enterprizes'),
(2, 'RR Vendors'),
(3, 'JK Suppliers');
-- --------------------------------------------------------
--
-- Table structure for table `vendor_services`
--
CREATE TABLE `vendor_services` (
`id` int(11) NOT NULL,
`vendor_id` int(11) NOT NULL,
`category_id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--
-- Dumping data for table `vendor_services`
--
INSERT INTO `vendor_services` (`id`, `vendor_id`, `category_id`) VALUES
(1, 1, 4),
(2, 1, 5),
(3, 1, 6),
(4, 1, 11),
(5, 2, 7),
(6, 2, 8),
(7, 2, 9),
(8, 3, 10),
(9, 3, 11);
--
-- Indexes for dumped tables
--
--
-- Indexes for table `categories`
--
ALTER TABLE `categories`
ADD PRIMARY KEY (`id`),
ADD KEY `category_id` (`category_id`);
--
-- Indexes for table `vendors`
--
ALTER TABLE `vendors`
ADD PRIMARY KEY (`id`);
--
-- Indexes for table `vendor_services`
--
ALTER TABLE `vendor_services`
ADD PRIMARY KEY (`id`),
ADD KEY `vendor_id` (`vendor_id`),
ADD KEY `category_id` (`category_id`);
--
-- AUTO_INCREMENT for dumped tables
--
--
-- AUTO_INCREMENT for table `categories`
--
ALTER TABLE `categories`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=12;
--
-- AUTO_INCREMENT for table `vendors`
--
ALTER TABLE `vendors`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4;
--
-- AUTO_INCREMENT for table `vendor_services`
--
ALTER TABLE `vendor_services`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=10;COMMIT;
CategoriesTable
$this->hasMany(‘Subcategories’, [ 'className'=> ‘Categories’,
'foreignKey' => 'category_id',
'conditions' => ['category_id!= 0']
]);
$this->belongsTo('MainCategories', [
'className'=> ‘Categories’,
'foreignKey' => 'category_id',
]);
Below is the query in oracle, please have a look, and modify it as per mysql,
added below insertion,
INSERT INTO VENDOR_SERVICES (ID, VENDOR_ID, CATEGORY_ID)
VALUES(11, 3, 3);
SELECT FRM.CATEGORY_ID, FRM.VENDOR_ID, FRM.VENDER_NAME,COUNT(VENDOR_ID) counts FROM (
SELECT distinct CT.CATEGORY_ID, VS.VENDOR_ID, VS.CATEGORY_ID VS_CATEGORY_ID,vn.ID, vn.NAME VENDER_NAME FROM CATEGORIES CT
INNER JOIN VENDOR_SERVICES VS ON VS.CATEGORY_ID=CT.CATEGORY_ID
INNER JOIN VENDORS VN ON VS.VENDOR_ID=VN.ID) frm
group by CATEGORY_ID, VENDOR_ID, VENDER_NAME

SQL - how to get all subcategory products incl. self products

I have a problem with my database and I hope you can help me with this.
I have tables like this:
categories
--------------------
|id | name | parent|
____________________
categories_x_products (m:n)
---------------------
|id | ctg_id | p_id |
---------------------
products
------------
| id, name |
------------
And my question is: "how to get all my & subcategories product count?"
For example:
categories:
id = 1, name = computers, parent = 0 (1 product)
id = 2, name = notebooks, parent = 1 (2 products)
and I want to get
computers : 3
notebooks : 2
I try this but does not working
select a.name, count(b.id)
FROM categories a
LEFT JOIN categories x ON x.id=a.parent
LEFT JOIN category_x_product b ON b.ctg_id=a.id
group by a.id
Thank you for answers.
Here is some example data:
-- Adminer 4.2.3 MySQL 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 `categories`;
CREATE TABLE `categories` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`parent` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `categories` (`id`, `name`, `parent`) VALUES
(1, 'computers', 0),
(2, 'notebooks', 1),
(3, 'lenovo', 2);
DROP TABLE IF EXISTS `products`;
CREATE TABLE `products` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `products` (`id`, `name`) VALUES
(1, 'lenovo thinkpad 001'),
(2, 'lenovo thinkpad 002'),
(3, 'lenovo thinkpad 003'),
(4, 'lenovo thinkpad 004'),
(5, 'lenovo thinkpad 005'),
(6, 'random comp.');
DROP TABLE IF EXISTS `product_x_category`;
CREATE TABLE `product_x_category` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`product_id` int(11) DEFAULT NULL,
`category_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `product_x_category` (`id`, `product_id`, `category_id`) VALUES
(1, 1, 3),
(2, 2, 3),
(3, 3, 3),
(4, 4, 3),
(5, 5, 3),
(6, 6, 1);
-- 2016-02-23 08:16:30
I've tried to run your SQL Query (Create table and insert value).
And I run this query
SELECT a.name, COUNT( b.id )
FROM categories a
LEFT JOIN product_x_category b ON b.category_id = a.id
GROUP BY a.id
And it returns this
This is your product_x_Category table (where category_id --> 3 = lenovo and category_id --> 1 = computer)
I think the result is what you want, isn't it?

Mysql BIGINT comparison not evaluating correctly

So I've been having a problem and either I am forgetting something fundamental or I found a bug. I've narrowed it down to this:
My table:
CREATE TABLE `tbl` (
`id` int(11) NOT NULL,
`timestmp` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Simple. My query:
insert into tbl (id, timestmp) values (1, 1)
on duplicate key update timestmp = if(values(timestmp) > timestmp,
values(timestmp), timestmp)
Table will contain
(1, 1)
Repeat the query with
values (1, 2)
Table will contain
(1, 2)
Repeat the query with
values (1, 1)
Table will still contain
(1, 2)
Great. Just what we want. Instead with this table:
CREATE TABLE `tbl` (
`id` int(11) NOT NULL,
`timestmp` bigint(20) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Let's do the same queries:
insert into tbl (id, timestmp) values (1, 1)
on duplicate key update timestmp = if(values(timestmp) > timestmp,
values(timestmp), timestmp)
Table contains:
(1, 1)
Query with:
values (1, 2)
Table contains:
(1, 1)
What? Let's try
values (1, -1)
Table contains:
(1, -1)
JKLFSD!!!!! What's going on? Is this supposed to happen? Am I completely misinterpreting something? Do I need a special function for bigint comparison?

MySQL Call Stored procedure from another stored procedure

Sorry for long POST:
Is it possible that I can call a Stored Procedures from another
Stored procedure in MySQL.
For example:
I have two tables (test and testcomp):
With the structures below:
-- Table structure for table test
CREATE TABLE IF NOT EXISTS `test` (
`t_id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
PRIMARY KEY (`t_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;
and
-- Table structure for table testcomp
CREATE TABLE IF NOT EXISTS `testcomp` (
`c_id` int(11) NOT NULL AUTO_INCREMENT,
`t_id` int(4) NOT NULL,
`place` varchar(255) NOT NULL,
PRIMARY KEY (`c_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;
Now I populated test table with:
INSERT INTO `test` (`t_id`, `name`) VALUES
(1, 'foo'),
(2, 'bar'),
(3, 'ma');
and table testcomp with:
INSERT INTO `testcomp` (`c_id`, `t_id`, `place`) VALUES
(1, 1, 'gugs'),
(2, 2, 'nyanga'),
(3, 1, 'gugs'),
(4, 3, 'skom');
Now if I have 2 Procedures:
First QryTestComp:
SELECT t_id, place FROM TestComp
The one above works as the just querying normal table:
But the Second One QryTestPlac, which calls the above procedure:
SELECT * FROM Test INNER JOIN QryTestComp ON Test.t_id = QryTestComp.t_id
Comes with a error:
It says Error: 1146 (42S01): Table 'mydb.qrytestcomp' doesn't exist.
It not a table but a procedure.
Pointer, please.
Regards,
--Jongi
you can't join onto a stored procedure, perhaps using views might be more suitable ?