JOIN Call table to grouping by Origination and Destination - php

It's a call system.
tables structure and data sample :
tbl_countries
CREATE TABLE tbl_countries
(
country_id int(11) PRIMARY KEY NOT NULL AUTO_INCREMENT,
country varchar(100) NOT NULL
);
INSERT INTO tbl_countries (country) VALUES ('Austria');
INSERT INTO tbl_countries (country) VALUES ('Brazil');
INSERT INTO tbl_countries (country) VALUES ('Denmark');
INSERT INTO tbl_countries (country) VALUES ('France');
INSERT INTO tbl_countries (country) VALUES ('Lebanon');
tbl_destination_clients
CREATE TABLE tbl_destination_clients
(
des_client_id int(11) PRIMARY KEY NOT NULL AUTO_INCREMENT,
des_client varchar(100) NOT NULL,
country_id int(11) NOT NULL,
CONSTRAINT tbl_destination_clients_ibfk_1 FOREIGN KEY (country_id) REFERENCES tbl_countries (country_id)
);
CREATE INDEX country_id ON tbl_destination_clients (country_id);
INSERT INTO tbl_destination_clients (des_client, country_id) VALUES ('961123456', 5);
INSERT INTO tbl_destination_clients (des_client, country_id) VALUES ('55123456', 2);
INSERT INTO tbl_destination_clients (des_client, country_id) VALUES ('45123456', 3);
tbl_origination_clients
CREATE TABLE tbl_origination_clients
(
orig_client_id int(11) PRIMARY KEY NOT NULL AUTO_INCREMENT,
orig_client varchar(100) NOT NULL,
country_id int(11) NOT NULL,
CONSTRAINT tbl_origination_clients_ibfk_1 FOREIGN KEY (country_id) REFERENCES tbl_countries (country_id)
);
CREATE INDEX country_id ON tbl_origination_clients (country_id);
INSERT INTO tbl_origination_clients (orig_client, country_id) VALUES ('33123456', 4);
INSERT INTO tbl_origination_clients (orig_client, country_id) VALUES ('43123456', 1);
tbl_calls
CREATE TABLE tbl_calls
(
call_id int(11) PRIMARY KEY NOT NULL AUTO_INCREMENT,
orig_client_id int(11) NOT NULL,
des_client_id int(11) NOT NULL,
call_duration int(11) NOT NULL,
CONSTRAINT tbl_calls_ibfk_1 FOREIGN KEY (orig_client_id) REFERENCES tbl_origination_clients (orig_client_id),
CONSTRAINT tbl_calls_ibfk_2 FOREIGN KEY (des_client_id) REFERENCES tbl_destination_clients (des_client_id)
);
CREATE INDEX des_client_id ON tbl_calls (des_client_id);
CREATE INDEX orig_client_id ON tbl_calls (orig_client_id);
INSERT INTO tbl_calls (orig_client_id, des_client_id, call_duration) VALUES (1, 3, 5);
INSERT INTO tbl_calls (orig_client_id, des_client_id, call_duration) VALUES (1, 3, 6);
INSERT INTO tbl_calls (orig_client_id, des_client_id, call_duration) VALUES (2, 4, 9);
INSERT INTO tbl_calls (orig_client_id, des_client_id, call_duration) VALUES (1, 1, 10);
Attemps :
I try to use JOIN between the same table tbl_calls, but it's not working ;(
But the Result of this sample data must be :
Origination Destination SUM(call_duration)
------------+------------+----------------
France Brazil 11 -> (5+6)
Austria Denmark 9
France Lebanon 10
Thank you #forpas
Query with adapted join column
select
co.country Origination,
cd.country Destination,
sum(c.call_duration) TotalDuration
from tbl_calls c
inner join tbl_destination_clients d on d.des_client_id = c.des_client_id
inner join tbl_origination_clients o on o.orig_client_id = c.orig_client_id
inner join tbl_countries cd on cd.country_id = d.country_id
inner join tbl_countries co on co.country_id = o.country_id
group by
co.country,
cd.country;

With grouping after multiple joins (tbl_countries must be joined twice for destination and origination)
and sum over call_duration:
select
co.country Origination,
cd.country Destination,
sum(c.call_duration) TotalDuration
from tbl_calls c
inner join tbl_destination_clients d on d.des_client_id = c.des_client_id
inner join tbl_origination_clients o on o.orig_client_id = c.des_client_id
inner join tbl_countries cd on cd.country_id = d.country_id
inner join tbl_countries co on co.country_id = o.country_id
group by
co.country,
cd.country;

Related

I have two values on the first row of the table it_courses field course_branch. When i join branch table with it_courses table result only one value

these are the tables
and it results
I have two values on the first row of the table it_courses field course_branch. When i join branch table with it_courses table result is like this.it doesnt shows the second value in the 1st row that was entered in the it_coursestable
Query :
SELECT branch.branch_name
FROM `branch`
JOIN `it_courses` ON it_courses.course_branch = branch.branch_id
You can try this database structure and query :
Table:
tbl_it_courses (id - PK, cource_name, branch_id - FK)
tbl_branch (id - PK, branch_id, branch_name)
Table : tbl_it_courses
CREATE TABLE tbl_it_courses (
id INT NOT NULL AUTO_INCREMENT,
cource_name VARCHAR(70) NOT NULL,
branch_id VARCHAR(70) DEFAULT NULL,
PRIMARY KEY(id)
);
INSERT INTO `tbl_it_courses` (`Id`, `cource_name`, `branch_id`) VALUES (NULL, 'PHP', '1,4'),(NULL, '.NET', '3'), (NULL, 'CCNA', '3');
Table : tbl_branch
CREATE TABLE tbl_branch (
id INT NOT NULL AUTO_INCREMENT,
branch_id VARCHAR(70) DEFAULT NULL,
branch_name VARCHAR(70) NOT NULL,
PRIMARY KEY(id)
);
INSERT INTO `tbl_branch` (`Id`, `branch_id`, `branch_name`) VALUES (NULL, 'Ern', 'brn92b224'),(NULL, 'Klm', 'brnaf3650'), (NULL, 'Tvm', 'brn272493');
Query :
SELECT tbl_it_courses.cource_name, (SELECT GROUP_CONCAT(tbl_branch.branch_name) FROM tbl_branch WHERE FIND_IN_SET(tbl_branch.id,tbl_it_courses.branch_id) > 0) as branch_name
FROM tbl_it_courses
I Hope It will Help you.
Try this.
SELECT branch.branch_id,it_courses.course_name
FROM `branch`
left JOIN `it_courses` ON LOCATE(branch.branch_name,it_courses.course_branch) > 0

How could i display the items from 3 tables joined

How could i display the items from 3 tables below joining using the product_tbl id.
and using foreach. or if there is any alternative way to display it.
The tables
I couldn't get the 3rd table or pictures table.
using my existing code below.
still error.
$product_list = DB::table('product_tbl')
->leftjoin('brand_tbl', 'product_tbl.id', '=', 'brand_tbl.product_id')
->select('*')
->get();
return vehicles_list;
$prod_list = array();
foreach ($product_list as $key => $value) {
$prod_list [$value->products_name][] = $value;
}
print_r($prod_list);
please help me thank you.
If your table structure isn't set in stone you might try the following structure for a more normalized and indexable structure. I made some changes - changing product to category, and brand to product. These labels made more sense to me as I worked with this. I also do full namespaced field names to make joining possible without aliasing all field names.
see the bottom of this post for the SQL to generate and populate these tables
Then a different query will definitely help. You're not joining on the picture table in your code.
select * from so_category
left outer join so_product on ( product_category_id = category_id)
left outer join so_picture on ( picture_category_id = category_id )
But this will probably not return your data like you want to consume it.
In which case the Mysql Group Concat Function might help.
SELET
so_category.*,
so_product.*,
(select GROUP_CONCAT( DISTINCT picture_url order by picture_url asc separator "," )) AS images
FROM so_category
LEFT OUTER JOIN so_product ON ( product_category_id = category_id)
LEFT OUTER JOIN so_picture ON ( picture_category_id = category_id )
GROUP BY product_id
Which yields results that do not duplicate data.
SQL to create and populate tables.
-- Create syntax for TABLE 'so_category'
CREATE TABLE `so_category` (
`category_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`category_name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`category_id`)
) ENGINE=InnoDB CHARSET=utf8;
-- Create syntax for TABLE 'so_picture'
CREATE TABLE `so_picture` (
`picture_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`picture_url` varchar(100) DEFAULT NULL,
`picture_category_id` int(11) unsigned DEFAULT NULL,
PRIMARY KEY (`picture_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- Create syntax for TABLE 'so_product'
CREATE TABLE `so_product` (
`product_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`product_name` varchar(100) DEFAULT NULL,
`product_brand_id` int(11) unsigned DEFAULT NULL,
`product_category_id` int(11) unsigned DEFAULT NULL,
PRIMARY KEY (`product_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `so_category` (`category_id`, `category_name`)
VALUES
(1, 'chocolate'),
(2, 'flower');
INSERT INTO `so_picture` (`picture_id`, `picture_url`, `picture_category_id`)
VALUES
(1, 'dmc1', 1),
(2, 'dmc2', 1),
(3, 'dmc3', 2),
(4, 'dmc4', 2),
(5, 'dmc5', 2);
INSERT INTO `so_product` (`product_id`, `product_name`, `product_brand_id`, `product_category_id`)
VALUES
(1, 'hershey', NULL, 1),
(2, 'tobleron', NULL, 1),
(3, 'oreo', NULL, 1),
(4, 'roses', NULL, 2),
(5, 'sunflower', NULL, 2);

How to check if values from the table 1 are used in table 2?

I have two tables employees and departments.
Departments:
create table dept (
id INT NOT NULL AUTO_INCREMENT,
dept_name VARCHAR(50) NOT NULL,
PRIMARY KEY (id)
);
Employees:
create table department_master (
id INT NOT NULL AUTO_INCREMENT,
dept_id INT NOT NULL,
emp_name VARCHAR(100) NOT NULL,
PRIMARY KEY (id)
);
I want to prevent departments being deleted from the UI if they are assigned to one of the employees in employee table. Left join is giving me duplicate values.
How do I see if the departments are being used in the employees table.
If you want to prevent a department from being deleted, you can simply add a foreign constraint to the table department_master for dept_id column.
create table department_master (
id INT NOT NULL AUTO_INCREMENT,
dept_id INT NOT NULL,
emp_name VARCHAR(100) NOT NULL,
PRIMARY KEY (id),
constraint con_dm foreign key dept_id references dept( id )
);
It's default behavior is ON DELETE RESTRICT which means that if there is atleast one row present in the department_master for a given dept_id, it can't be deleted from dept table.
If you want to fetch, the department that don't have any employee record, you can use NOT EXISTS:
select *
from dept d
where not exists (
select 1
from department_master m
where d.id = m.dept_id
);
I believe you want a count of the number of employees grouped by the department, like so:
SELECT count(*) as employees, d.dept_name FROM dept AS d LEFT JOIN department_master AS e ON e.dept_id = d.id group by e.dept_id

Query consult doctrine composite key

Hello I am try to take data with dictrine 2.5 from a table but I do not know how to do it.
SQL FILE
DROP DATABASE composite_key;
CREATE DATABASE composite_key;
USE composite_key;
CREATE TABLE company (
id_company INT NOT NULL AUTO_INCREMENT,
name VARCHAR(200) NULL,
PRIMARY KEY (id_company)
);
CREATE TABLE users (
id_user INT NOT NULL AUTO_INCREMENT,
name VARCHAR(200) null,
PRIMARY KEY (id_user)
);
CREATE TABLE reference (
id_company INT NOT NULL,
id_user INT NOT NULL,
createat TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id_company),
FOREIGN KEY (id_company) REFERENCES company(id_company),
FOREIGN KEY (id_user) REFERENCES users(id_user)
);
INSERT INTO users (`name`) VALUES ('test1');
INSERT INTO users (`name`) VALUES ('test2');
INSERT INTO users (`name`) VALUES ('test3');
INSERT INTO company (`name`) VALUES ('company1');
INSERT INTO company (`name`) VALUES ('company2');
INSERT INTO company (`name`) VALUES ('company3');
INSERT INTO reference (`id_company`,`id_user`) VALUES (1,1);
INSERT INTO reference (`id_company`,`id_user`) VALUES (2,2);
INSERT INTO reference (`id_company`,`id_user`) VALUES (3,3);
QUERY WHICH I HAVE TRIED
$dql = "SELECT r FROM CompositeBundle:Reference r JOIN CompositeBundle:Company c JOIN CompositeBundle:Users u WHERE c.idCompany = 1 AND u.idUser = 1 ";
$dql = "SELECT r FROM CompositeBundle:Reference r JOIN r.idUser JOIN r.idCompany WHERE r.idCompany = 1 AND r.idUser = 1 ";
If somone know to do these dql please sat It.

Select rows that match right side of one to many reationship in MySql

I have 4 tables. One for companies, one for products one for company address, and one for company directors.
The products, director and address tables are in a one to many relationship to the company table.
So one company can have many products, many addresses and many directors.
CREATE TABLE IF NOT EXISTS `companies` (
`company_id` int(11) NOT NULL AUTO_INCREMENT,
`company_name` varchar(50) NOT NULL,
PRIMARY KEY (`company_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
CREATE TABLE IF NOT EXISTS `products` (
`product_id` int(11) NOT NULL AUTO_INCREMENT,
`company_id` int(11) NOT NULL,
`product` varchar(50) NOT NULL,
PRIMARY KEY (`product_id`),
KEY `company_id` (`company_id`),
KEY `product` (`product`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ;
CREATE TABLE IF NOT EXISTS `directors` (
`director_id` int(11) NOT NULL AUTO_INCREMENT,
`company_id` int(11) NOT NULL,
`surname` varchar(100) NOT NULL,
`dob` date NOT NULL,
PRIMARY KEY (`director_id`),
KEY `company_id` (`company_id`),
KEY `surname` (`surname`),
KEY `dob` (`dob`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ;
CREATE TABLE IF NOT EXISTS `addresses` (
`address_id` int(11) NOT NULL AUTO_INCREMENT,
`company_id` int(1) NOT NULL,
`postcode` varchar(10) NOT NULL,
PRIMARY KEY (`address_id`),
KEY `company_id` (`company_id`),
KEY `postcode` (`postcode`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=11 ;
INSERT INTO `companies` (`company_id`, `company_name`) VALUES
(1, 'Honda'),
(2, 'Toyota');
INSERT INTO `products` (`product_id`, `company_id`, `product`) VALUES
(1, 1, 'Civic'),
(2, 1, 'Accord'),
(3, 2, 'Corolla'),
(4, 2, 'Prius'),
(5, 1, 'CRV');
INSERT INTO `directors` (`director_id`, `company_id`, `surname`, `dob`) VALUES
(1, 1, 'Jones', '1990-09-09'),
(2, 1, 'Smith', '1980-08-08'),
(3, 2, 'Lucas', '1970-07-07'),
(4, 1, 'Kelly', '1960-06-06'),
(5, 2, 'Monty', '1950-05-05');
INSERT INTO `addresses` (`address_id`, `company_id`, `postcode`) VALUES
(6, 1, '12345'),
(7, 2, '23456'),
(8, 1, '34567'),
(9, 2, '45678'),
(10, 1, '56789');
Im trying to write an efficient query (using MySql / PDO) to find products for companies that match match directors (surname AND dob) and addresses (postcode).
I just want to list one matching product per row, not list every director or postcode separately.
So far I have the below query, which seems to work, but it's ugly and I suspect a ridiculous way to go about this in terms of speed and efficiency.
SELECT product
FROM products p
LEFT JOIN companies c USING(company_id)
WHERE :lname IN (
SELECT surname
FROM directors d
WHERE c.company_id = d.company_id )
AND :dob IN (
SELECT dob
FROM directors d
WHERE c.company_id = d.company_id )
AND :postcode IN (
SELECT postcode
FROM addresses a
WHERE c.company_id = a.company_id )
Thank you in advance for your help.
Unsure why you need subqueries at all?
SELECT p.product FROM products p
INNER JOIN companies c USING(company_id)
INNER JOIN directors d ON d.company_id = c.company_id AND d.surname = 'Jones' AND d.dob = '1990-09-09'
INNER JOIN addresses a ON a.company_id = c.company_id AND a.postcode = '12345'
Or
SELECT p.product FROM products p
INNER JOIN companies c USING(company_id)
INNER JOIN directors d USING(company_id)
INNER JOIN addresses a USING(company_id)
WHERE d.surname = 'Jones'
AND d.dob = '1990-09-09'
AND a.postcode = '12345'
If you do an EXPLAIN on these two queries, you'll see they end up the same internally.
At the very least, the two subqueries on directors can be unified by rewriting them with the exists operator instead of in. For good measures, I rewrote the entire query with this operator, although it's not strictly necessary:
SELECT product
FROM products p
LEFT JOIN companies c USING(company_id)
WHERE EXISTS (SELECT *
FROM directors d
WHERE c.company_id = d.company_id AND
(:lname = d.lanme OR :dob = d.dob)) AND
EXISTS (SELECT *
FROM addresses a
WHERE c.company_id = a.company_id AND :postcode = a.postcode)

Categories