MySQL query parameters in a table field - mysql

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

Related

how to find date difference from two different table in mys

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

Get the longest and shortest "chains" in MySQL?

Consider this schema:
create table Operation(id integer, name varchar(100));
create table Pipeline(operation_in integer, operation_out integer);
Pipeline has foreign keys to Operations, so pipelines are chained, in a way. operation_out is nullable. How do I get the names of operations in both the longest and the shortest pipeline chains using MySQL?
Operations look like this:
INSERT INTO Operation VALUES (1, 'operation one');
While the pipelines look something like this:
INSERT INTO Pipeline VALUES (1, 2);
INSERT INTO Pipeline VALUES (2, 4);
INSERT INTO Pipeline VALUES (4, 7);
INSERT INTO Pipeline VALUES (7, NULL);
I.e. the chain here would be operations with ID 1, 2, 4, 7 and expected result along the lines of:
"operation one", "operation two", "operation four"...
After a few hours of research, I am not sure quite what the solution I am looking for.
Any MySQL version is applicable.
In MySQL 8.x you can use a Recursive CTE to find the chains you need.
For example:
with recursive
a as (
select
p.operation_in,
p.operation_out as current_out,
o.name as op_names,
concat('', p.operation_in) as chain,
1 as size
from pipeline p
join operation o on o.id = p.operation_in
where not exists (
select 1 from pipeline p2 where p2.operation_out = p.operation_in
)
union all
select
a.operation_in,
p.operation_out,
concat(op_names, ', ', o.name),
concat(chain, ',', p.operation_in),
size + 1
from a
join pipeline p on p.operation_in = a.current_out
join operation o on o.id = p.operation_in
),
chains as (
select * from a where current_out is null
)
select op_names, chain, size
from chains
where size = (select max(size) from chains) -- finds the longest one
or size = (select min(size) from chains); -- finds the shortest one
Result:
op_names chain size
--------------------------------- ------- ----
op-nine, op-six 9,6 2
op-one, op-two, op-four, op-seven 1,2,4,7 4
The data script I used is:
create table operation (id integer, name varchar(100));
create table pipeline (operation_in integer, operation_out integer);
insert into operation values (1, 'op-one');
insert into operation values (2, 'op-two');
insert into operation values (4, 'op-four');
insert into operation values (6, 'op-six');
insert into operation values (7, 'op-seven');
insert into operation values (9, 'op-nine');
insert into pipeline values (1, 2);
insert into pipeline values (2, 4);
insert into pipeline values (4, 7);
insert into pipeline values (7, null);
insert into pipeline values (9, 6);
insert into pipeline values (6, null);

SQL query from a table

For my CIS class, I have SQL project, I'm still very new to SQL and trying to learn it. Any help would be greatly appreciated.
Query: Write a query to show the total value of all the orders that customers living in San Jose or Turlock have placed.
This is what I tried and giving me an error:
select SUM(price * quantity) as Revenue
FROM customer,salesorder
where customer.cno = salesorder.cno AND
zip = 95124 AND zip = 95380
AND zip = 95382
The error I'm getting is: #1054 - Unknown column 'price' in 'field list'
Table: Table
Database codes:
create table zipcode (
zip integer(5) primary key,
city varchar(30),
State varchar(20));
create table employee (
eno varchar(10) primary key,
ename varchar(30),
zip integer(5) references zipcode(zip),
hire_date date);
create table book (
bno integer(5) primary key,
bname varchar(30),
qoh integer(5) not null,
price dec(6,2) not null);
create table customer (
cno integer(5) primary key,
cname varchar(30),
street varchar(30),
zip integer(5) references zipcode(zip),
phone char(12));
create table salesOrder (
ono integer(5) primary key,
cno integer(5) references customer(cno),
eno varchar(10) references employees(Eno),
received date,
shipped date
);
create table orderLine (
ono integer(5) references salesOrder(ono),
bno integer(5) references book(bno),
quantity integer(10) not null,
primary key (ono, bno));
insert into zipcode values (98225, 'Bellingham', 'WA');
insert into zipcode values (95388, 'Winton', 'CA');
insert into zipcode values (44242, 'Stow', 'OH');
insert into zipcode values (61536, 'Hanna city', 'IL');
insert into zipcode values (01254, 'Richmond', 'MA');
insert into zipcode values (95124, 'San Jose', 'CA');
insert into zipcode values (95382, 'Turlock', 'CA');
insert into zipcode values (95380, 'Turlock', 'CA');
insert into zipcode values (98102, 'Seattle', 'WA');
insert into employee values ('P0239401', 'Jones Hoffer',98225, '2000-12-12');
insert into employee values ('P0239402', 'Jeffrey Prescott',95388, '2016-11-07');
insert into employee values ('P0239403', 'Fred NcFaddeb',95124, '2008-09-01');
insert into employee values ('P0239404', 'Karen Ives',98102, '2014-05-21');
insert into book values (10501, 'Forensic Accounting',200, 229.99);
insert into book values (10502, 'SAP Business One',159, 149.99);
insert into book values (10503, 'Fraud Cases',190, 179.99);
insert into book values (10504, 'CPA Review',65, 279.99);
insert into book values (10605, 'Quickbooks for Business',322, 59.99);
insert into book values (10704, 'Financial Accounting',129, 164.99);
insert into book values (10879, 'Managerial Accounting',155, 114.99);
insert into book values (10933, 'Cost Accounting',122, 219.99);
insert into book values (10948, 'Intermediate Accounting',123, 164.99);
insert into book values (10965, 'Accounting Information Systems',211, 259.99);
insert into book values (10988, 'XBRL in Nutshell',124, 109.99);
insert into customer values (23511, 'Michelle Kuan', '123 Main St.',98225, '360-636-5555');
insert into customer values (23512, 'George Myer', '237 Ash Ave.',95124, '312-678-5555');
insert into customer values (23513, 'Richard Gold', '111 Inwood St.',95124, '312-883-7337');
insert into customer values (23514, 'Robert Smith', '54 Gate Dr.',95388, '206-832-1221');
insert into customer values (23515, 'Christopher David', '777 Loto St.',98225, '360-458-9878');
insert into customer values (23516, 'Adam Beethoven', '234 Park Rd.',95380, '209-546-7299');
insert into customer values (23517, 'Ludwig Bach', '5790 Walnut St.',95382, '209-638-2712');
insert into customer values (23518, 'Kathleen Pedersen', '1233 Federal Ave E', 98102, '360-573-7239');
insert into salesOrder values (1020, 23511, 'P0239403', '2018-01-13', '2018-01-15');
insert into salesOrder values (1021, 23513, 'P0239401', '2018-01-13', '2018-01-16');
insert into salesOrder values (1022, 23513, 'P0239402', '2018-01-15', '2018-01-17');
insert into salesOrder values (1023, 23512, 'P0239403', '2018-01-16', '2018-01-18');
insert into salesOrder values (1024, 23511, 'P0239402', '2018-01-18', '2018-01-20');
insert into salesOrder values (1025, 23511, 'P0239403', '2018-01-29', '2017-01-31');
insert into salesOrder values (1026, 23512, 'P0239404', '2018-01-30', '2018-01-31');
insert into salesOrder values (1027, 23512, 'P0239402', '2018-01-30', '2018-01-31');
insert into salesOrder values (1028, 23512, 'P0239404', '2018-01-30', '2018-01-31');
insert into salesOrder (ONO, CNO, ENO, RECEIVED) values (1029, 23513, 'P0239402', '2018-01-31');
insert into salesOrder (ONO, CNO, ENO, RECEIVED) values (1030, 23511, 'P0239401', '2018-01-31');
insert into orderLine values (1020, 10501,7);
insert into orderLine values (1020, 10502,15);
insert into orderLine values (1020, 10504,3);
insert into orderLine values (1020, 10503,6);
insert into orderLine values (1021, 10605,4);
insert into orderLine values (1022, 10605,2);
insert into orderLine values (1022, 10704,4);
insert into orderLine values (1023, 10879,4);
insert into orderLine values (1023, 10988,19);
insert into orderLine values (1024, 10502,7);
insert into orderLine values (1024, 10988,2);
insert into orderLine values (1025, 10502,4);
insert into orderLine values (1025, 10988,3);
insert into orderLine values (1025, 10948,2);
insert into orderLine values (1026, 10965,15);
insert into orderLine values (1026, 10933,5);
insert into orderLine values (1027, 10933,21);
insert into orderLine values (1028, 10933,9);
insert into orderLine values (1028, 10965,11);
insert into orderLine values (1029, 10933,4);
insert into orderLine values (1029, 10965,10);
insert into orderLine values (1029, 10988,3);
insert into orderLine values (1030, 10965,6);
You can try this.
That no make sense on
AND zip = 95124
AND zip = 95380
AND zip = 95382
I guess you want to use IN
From your table schema join Orderline and Book you will get price and quantity
select SUM(b.price * o.quantity)
FROM customer c
INNER JOIN salesorder s ON c.cno = s.cno
INNER JOIN Orderline o ON s.ono = o.ono
INNER JOIN Book b ON b.bno = o.bno
where zip IN (95124,95380,95382);
sqlfiddle : http://sqlfiddle.com/#!9/07a9c0b/8
Once check the table where the column price exists in...I see it in the table book
and yet you did not use the table book in your query... so this is how you should do it..
select SUM(Book.price * Orderline.quantity)
FROM customer
INNER JOIN salesorder ON customer.cno = salesorder.cno
INNER JOIN Orderline ON salesorder.ono = Orderline.ono
INNER JOIN Book ON Book.bno = Orderline.bno
where customer.zip IN (95124,95380,95382);
The error I'm getting is: #1054 - Unknown column 'price' in 'field list'`
As per your query you have not added the table having price column.
If you can see your DDL statements price column is in book table and you have to join this table to get the required result.
I guess this should work
SELECT SUM(book.price*orderline.quantity) AS "order value" from customer
JOIN salesorder
ON salesorder.cno=customer.cno
JOIN orderline
ON salesorder.ono=orderline.ono
JOIN book
ON orderline.bno=book.bno
JOIN zipcode
ON customer.zip = zipcode.zip
WHERE city in ('Turlock', 'San Jose')
First thing that needs correction is an aggregate function like sum, avg etc need a group clause as well. For example
select sum(price * quantity) as revenue from customers c, salesorder s where
c.customer_no=s.customer_no group by c.customer_no
It will return the total revenue a single customer generated . Second thing is
for filtering based on several Zip Code you can use IN clause like
where zip_no in ('A','B','C')
Third please check you are writing correct column name and spelling of column as well of price

Select rows where field in joining table not same value in every row

Is it possible in MySQL to see if a field in a join table does not have the same value in every row.
I tried to put it in an easy example in this sqlfiddle
-- Create tables
create table tbl_cake (
id INT
);
create table tbl_cake_piece (
id INT,
cake_id INT,
share INT
);
-- This cake is divided in 2 pieces with size 1/2
insert into tbl_cake values (1);
insert into tbl_cake_piece values (1, 1, 2);
insert into tbl_cake_piece values (2, 1, 2);
-- This cake is divided in 1 piece with size 1/2 and 2 pieces with size 1/4
insert into tbl_cake values (2);
insert into tbl_cake_piece values (3, 2, 2);
insert into tbl_cake_piece values (4, 2, 4);
insert into tbl_cake_piece values (5, 2, 4);
-- I want to select cakes that are not divided in equals pieces
-- So this query should return cake with id '2'
select * from tbl_cake c
join tbl_cake_piece p on p.cake_id = c.id
Cakes that aren't cut in X equal pieces
select cake_id
from tbl_cake_piece
group by cake_id
having count(distinct share) > 1

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