how to find date difference from two different table in mys - mysql

I have two tables
1)LEAD TABLE (which have 3 columns)
Lead_ID || Created_Date || Industry
2)ACCOUNTS TABLE (which have 4 columns)
Account_ID||Created_Date|| Revenue_Range|| Lead_ID
How would I get the average number of days between a lead created and an account created

Don't pay attention to mess in data, I just randomly populated it.
Query returns leadId and difference in days between lead.created_date and account.created_date.
Query:
create table Leads
(
leadId int not null,
created_date datetime,
industry varchar(10),
PRIMARY KEY (leadId)
);
create table Accounts
(
accountId int not null,
created_date datetime,
revenue_range varchar(10),
leadId int not null,
FOREIGN KEY (leadId) REFERENCES Leads(leadId)
);
insert into Leads
values
(1, '2020-01-01', 'a'),
(2, '2020-01-02', 'b'),
(3, '2020-01-03', 'c'),
(4, '2020-02-01', 'd'),
(5, '2020-03-01', 'e');
insert into Accounts
values
(1, '2020-01-03', '1k', 1),
(2, '2020-03-10', '2k', 5),
(3, '2020-02-03', '3k', 2);
select
-- l.leadId,
-- l.created_date as LeadCreatedDate,
-- a.created_date as AccountCreatedDate,
-- ABS is used because it returns with minus sign
AVG(ABS(DATEDIFF(l.created_date, a.created_date))) as AvgDifferenceInDaysBetweenCreation
from Leads as l
inner join Accounts as a
on l.leadId = a.leadId;
You can try it out at SQLize Online

Related

Query that join two tables, shows all rows from first table and from second only the row that has the date bigger than today and closer to today

I have two tables, partners and tasks. I would like to write a query that shows all the partners and if there are tasks show only one >= than today (date). It is important that the task is the immediately next to today as date, not the first >= than today that is in the db.
Please find the tables and code below. My problem is that the query does not return the immediately next value to the inserted date, but returns the >= that find in the database.
-- create a table
CREATE TABLE partners
(
id INTEGER PRIMARY KEY,
code INTEGER,
name TEXT
);
CREATE TABLE tasks
(
id INTEGER PRIMARY KEY,
code INTEGER,
comment TEXT,
data INTEGER
);
-- insert some values
INSERT INTO partners VALUES (1, 222, 'M');
INSERT INTO partners VALUES (2, 333, 'F');
INSERT INTO partners VALUES (3, 555, 'F-m');
INSERT INTO tasks VALUES (1, 333, 'f', 2020 );
INSERT INTO tasks VALUES (2, 333, 'f', 2022 );
INSERT INTO tasks VALUES (3, 333, 'f', 2021 );
INSERT INTO tasks VALUES (4, 333, 'f-i', 2023 );
INSERT INTO tasks VALUES (5, 222, 'm', 2021 );
INSERT INTO tasks VALUES (6, 444, 'F', 2025 );
-- fetch some values
SELECT *
FROM partners
LEFT JOIN tasks ON partners.code = tasks.code
WHERE tasks.data >= '2021'
GROUP BY tasks.code
ORDER BY tasks.data ASC;
Desired Result / Query Output:
1 , 222, M, m, 2021
2 , 333, F, f, 2021
3 , 555, F-m, No Task

MySQL query parameters in a table field

Good afternoon.
I have two tables:
1 - table1 - (id, address, who_lives) who_lives field - text, comma-separated list of identifiers
2 - table2 - (id, name_of_resident)
composition of table 1
12| US Oregon | 12,13
14| US Washington| 9,11
composition of table 2
9 |Petrov
11|Sidorov
12|Ivanov
13|Popov
How to make MySQL request, preferably via join, that the result was
US Oregon |Ivanov,Popov
US Washington|Petrov,Sidorov
If possible, replace the comma with the br tag: Ivanov,Popov -> Ivanov >br< Popov
SELECT table1.address, GROUP_CONCAT(table2.name_of_resident SEPARATOR '<br>')
FROM table1
JOIN table2 ON FIND_IN_SET(table2.id, table1.who_lives)
GROUP BY table1.address
DEMO
That is not how you design tables. Don't do comma separated listes. Do either a (foreign) key from table 2 to table 1, or a table with table1.id and table2.id for each relation.
Then writing the query will be easier.
create table state (
state_id int primary key,
address varchar(255)
);
create table resident (
resident_id int primary key,
name varchar(255)
);
create table who_lives (
state_id int,
resident_id int,
primary key (state_id, resident_id)
);
insert into state values (12, 'US Oregon');
insert into state values (14, 'US Washington');
insert into resident values (9, 'Petrov');
insert into resident values (11, 'Sidorov');
insert into resident values (12, 'Ivanov');
insert into resident values (13, 'Popov');
insert into who_lives values (12, 12);
insert into who_lives values (12, 13);
insert into who_lives values (14, 9);
insert into who_lives values (14, 11);
select address, group_concat(name)
from state
join who_lives using (state_id)
join resident using (resident_id)
group by state_id;
http://sqlfiddle.com/#!9/e7041f/2

Get the summation of two tables columns

I have three tables. I want to write a query to calculate the total handling cost of each order using the tables in MySQL.
create table orders(id integer, packaging varchar(100), delivery
varchar(100));
create table packaging_cost_tbl(packaging_type varchar(100), packaging_cost
integer);
create table delivery_cos_tbl(delivery_type varchar(100), delivery_cost
integer);
insert into orders(id, packaging, delivery) values(1, "Large", "Fast"),(2,
"Small", "Fast"), (3, "Large", "Express"), (4, "Medium", "Standard"), (5,
"Fragile", "Express"), (6, "Medium", "Fast"), (7, "Medium", "Standard");
insert into packaging_cost_tbl(packaging_type, packaging_cost)
values("Small", 2), ("Medium", 5), ("Large", 8), ("Fragile", 10);
insert into delivery_cost_tbl(delivery_type, delivery_cost)
values("Standard", 3), ("Fast", 7), ("Express", 15);
enter image description here
I have mentioned above create table queries and data insert queries for each tables. Output should be,
Order ID
Total handling cost( handling cost=packaging cost + delivery cost)
I'd join the orders table on the two others and sum their costs:
SELECT id, packaging_cost + delivery_cost
FROM orders o
JOIN packaging_cost_tbl p ON o.pacakging = p.packaging_type
JOIN delivery_cost_tbl d ON o.delivery = d.delivery_type

mysql running total as view

I am still an sql greenhorn and try to convert this script, building a running total as view in mysql:
DROP TABLE IF EXISTS `table_account`;
CREATE TABLE `table_account`
(
id int(11),
account int(11),
bdate DATE,
amount DECIMAL(10,2)
);
ALTER TABLE `table_account` ADD PRIMARY KEY(id);
INSERT INTO `table_account` VALUES (1, 1, '2014-01-01', 1.0);
INSERT INTO `table_account` VALUES (2, 1, '2014-01-02', 2.1);
INSERT INTO `table_account` VALUES (4, 1, '2014-01-02', 2.2);
INSERT INTO `table_account` VALUES (5, 1, '2014-01-02', 2.3);
INSERT INTO `table_account` VALUES (3, 1, '2014-01-03', 3.0);
INSERT INTO `table_account` VALUES (7, 1, '2014-01-04', 4.0);
INSERT INTO `table_account` VALUES (6, 1, '2014-01-06', 5.0);
INSERT INTO `table_account` VALUES (8, 1, '2014-01-07', 6.0);
SET #iruntot:=0.00;
SELECT
q1.account,
q1.bdate,
q1.amount,
(#iruntot := #iruntot + q1.amount) AS runningtotal
FROM
(SELECT
account AS account,
bdate AS bdate,
amount AS amount
FROM `table_account`
ORDER BY account ASC, bdate ASC) AS q1
This is much more faster than building a sum over the whole history on each line.
The problems I cannot solve are:
Set in view
Subquery in view
I think it might be posssible to use some kind of JOIN instead of "SET #iruntot:=0.00;"
and use two views to prevent the need of a subquery.
But I do know how.
Will be happy for any hints to try.
Regards,
Abraxas
MySQL doesn't allow subqueries in the from clause for a view. Nor does it allow variables. You can do this with a correlated subquery, though:
SELECT q.account, q.b_date, q.amount,
(SELECT SUM(q2.amount)
FROM myview1 q2
WHERE q2.account < q.account OR
q2.account = q.account and q2.date <= q.date
) as running total
FROM myview1 q;
Note that this assumes that the account/date column is unique -- no repeated dates for an account. Otherwise, the results will not be exactly the same.
Also, it seems a little strange that you are doing a running total across all accounts and dates. I might expect a running total within accounts, but this is how you formulated the query in the question.

Efficient MySQL Database Design

I'm working on a small program for my school and I have a question about the following DB design.
The admin will assign subjects to teachers via an online form.
An example of a subject would be something like:
Subject Field 1: (Grade 5 Math: Teaching 5/1, 5/2 and 5/3) [Text Field]
Subject Field 2: (Grade 6 Math: Teaching 6/2 and 6/6) [Text Field]
I have added 7 subjects fields per their request as there won't be anyone that will exceed 7 subjects.
Each Subject Field will have required things to complete such as lesson plans, course syllabus etc...
Each requirement will have the following requirements:
Language (Language 1, Language 2 or Both) [Drop Down]
Type (Printed, File or Both) [Drop Down]
Time (Semester 1, Semester 2 or both) [Drop Down]
So far I have come up with this DB design:
ID (Primary, Auto Incremented)
TID (Teacher ID)
Year
Subject1
Subject1Requirement1
Subject1Requirement2
Subject1Requirement3
TimeSent
TimeReviewed
Subject2
Subject2Requirement1
Subject2Requirement2
Subject2Requirement3
TimeSent
TimeReviewed
Subject3
Subject3Requirement1
Subject3Requirement2
Subject3Requirement3
TimeSent
TimeReviewed
Continued to Subject 7.
I feel that there is a more efficient way of doing it but just can't think of a better way.
Thanks.
If there's no relationship between teacher's subjects, you can design 3 tables like the following
Teachers TeacherSubjects SubjectRequirements
---------- --------------- --------------------
ID SubjectID ----> SubjectID
TID --\ SubjectName SubjectRequirement
Year \--> TID Language
TimeSent Type
TimeReviewed Time
In such design
Each teacher can have multiple subjects (not limited to 7 subjects)
Each teacher's subject have multiple requirements (not limited to 5 requrirements)
Sample data
INSERT INTO Teachers(ID, TID, Year) VALUES (1,'LiuYan', 2012);
INSERT INTO Teachers(ID, TID, Year) VALUES (2,'Emily', 2012);
INSERT INTO TeacherSubjects (SubjectID, SubjectName, TID) VALUES ('SubjectID_1', 'SubjectName1', 'LiuYan');
INSERT INTO TeacherSubjects (SubjectID, SubjectName, TID) VALUES ('SubjectID_2', 'SubjectName2', 'LiuYan');
-- ...
INSERT INTO TeacherSubjects (SubjectID, SubjectName, TID) VALUES ('SubjectID_N', 'SubjectNameN', 'LiuYan');
INSERT INTO TeacherSubjects (SubjectID, SubjectName, TID) VALUES ('SubjectID_N+1', 'SubjectName N+1', 'Emily');
INSERT INTO TeacherSubjects (SubjectID, SubjectName, TID) VALUES ('SubjectID_N+2', 'SubjectName N+2', 'Emily');
-- ...
INSERT INTO TeacherSubjects (SubjectID, SubjectName, TID) VALUES ('SubjectID_M', 'SubjectName M', 'Emily');
INSERT INTO SubjectRequirements (SubjectID, SubjectRequirement, Language, Type, Time) VALUES ('SubjectID_1', 'Curriculum', 'Language 1', 'Printed', 'Semester 1');
INSERT INTO SubjectRequirements (SubjectID, SubjectRequirement, Language, Type, Time) VALUES ('SubjectID_1', 'Course Syllabus', 'Language 2', 'File', 'Semester 2');
INSERT INTO SubjectRequirements (SubjectID, SubjectRequirement, Language, Type, Time) VALUES ('SubjectID_1', 'Learning Management', 'Both Language', 'Both Type', 'Both Semester');
--...
INSERT INTO SubjectRequirements (SubjectID, SubjectRequirement, Language, Type, Time) VALUES ('SubjectID_N+1', 'Curriculum', 'Language 2', 'Both Type', 'Semester 2');
--...
On of the key aspects of database is having relationships (links) between tables - so that if a table (row) needs to refer to something else that is different then use another table and link together with foreign keys - this table, in our case TeacherSubject is a junction table
To give you a brief look of how I'd implement your requirements I think we need three tables, and the SubjectsTeacher below is a linking table to join the two.
You define each subject and teacher and then add entries to the TeacherSubject table to associate teachers with subjects.
To create the database:
CREATE TABLE `Subject` (
`SID` INTEGER NOT NULL AUTO_INCREMENT ,
`Name` VARCHAR(100) NOT NULL ,
`Curriculum` INTEGER NOT NULL ,
`Syllabus` INTEGER NOT NULL ,
`LearnManagement` INTEGER NOT NULL ,
`Individual Analysis` INTEGER NOT NULL ,
PRIMARY KEY (`SID`)
);
CREATE TABLE `Teachers` (
`TID` INTEGER NOT NULL AUTO_INCREMENT ,
`Name` VARCHAR(100) NOT NULL ,
PRIMARY KEY (`TID`)
);
CREATE TABLE `TeacherSubject` (
`id` INTEGER NOT NULL AUTO_INCREMENT ,
`SID_Subject` INTEGER NOT NULL ,
`TID_Teachers` INTEGER NOT NULL ,
PRIMARY KEY (`id`)
);
Then add the foreign keys that tells the database how your fields are linked - this step is important as it will ensure that you maintain data integrity and cannot insert bad data into this data.
ALTER TABLE `TeacherSubject` ADD FOREIGN KEY (SID_Subject) REFERENCES `Subject` (`SID`);
ALTER TABLE `TeacherSubject` ADD FOREIGN KEY (TID_Teachers) REFERENCES `Teachers` (`TID`);
Then setup a few rows for test.
INSERT INTO `Subject` (`SID`, `Name`, `Curriculum`, `Syllabus`, `LearnManagement`, `Individual Analysis`) VALUES
(1, 'Subject1', 1, 2, 3, 4),
(2, 'Subject1', 1, 2, 3, 4),
(3, 'Subject2', 1, 2, 3, 4),
(4, 'Subject3', 1, 2, 3, 4),
(5, 'Subject4', 1, 2, 3, 4);
INSERT INTO `Teachers` (`Name`) VALUES ('Teacher 1');
INSERT INTO `Teachers` (`Name`) VALUES ('Teacher 2');
INSERT INTO `TeacherSubject` (`id`, `SID_Subject`, `TID_Teachers`) VALUES
(1, 1, 1),
(2, 2, 1),
(3, 3, 2),
(4, 4, 2),
(5, 1, 2);
And finally to find out which subject teacher#1 has:
select * from TeacherSubject
INNER JOIN Teachers on TID=TID_Teachers
WHERE TID_Teachers=1