Related
I have created an entity tblPerson and from this entity I need to get the bGroup of t.adminID and the bGroup from the d.personID. I have tried the below query but it's not returning anything.
`
SELECT t.adminID, p.firstName, p.lastName, t.transID, t.transDate, t.donationID, p.bGroup, b.bankName, d.personID AS 'Donor ID', 'Donor BGroup'
FROM tblTrans t
JOIN tblAdmin a ON t.adminID = a.adminID
JOIN tblPerson p ON a.personID = p.personID
JOIN tblDonation d ON t.donationID = d.donationID
JOIN tblBank b ON d.bankID = b.bankID
WHERE 'Donor BGroup' IN
(SELECT p.bGroup
FROM tblPerson p
JOIN tblDonation d ON p.personID = d.personID
JOIN tblTrans t ON d.donationID = t.donationID);
`
When I execute the subquery, it gives me the bGroup of the d.personID, what do you think is going on, and maybe any alternatives, please?
Sample Data
INSERT INTO tblPerson (personID, firstName, lastName, bGroup)
VALUES ('1A', 'John', 'Doe', 'XY'),
('2A', 'Joe', 'Bishop', 'AB'),
('1B', 'Elly', 'James', 'OP'),
('2B', 'Andre', 'Butch', 'XY'),
('3A', 'Amy', 'Gree', 'AB'),
('3B', 'Alfred', 'Black', 'OP'),
('4C', 'James', 'Brown', 'XY');
INSERT INTO tblAdmin (adminID, personID, description)
VALUES (1, '1A', 'Whatever.'),
(2, '1B', ''),
(3, '4C', 'Anything.'),
(4, '1A', '');
INSERT INTO tblDonation (donationID, bankID, personID, donationDate)
VALUES (1, 1, '3B', '2018-12-27'),
(2, 1, '2A', '2022-12-28'),
(3, 2, '3A', '2022-03-23'),
(4, 2, '4C', '2022-06-19'),
(5, 3, '1B', '2022-08-19'),
(6, 3, '2B', '2022-08-08'),
(7, 3, '3B', '2022-07-20'),
(8, 2, '4C', '2022-11-26'),
(9, 1, '3B', '2022-11-26'),
(10, 2, '2A', '2022-01-16');
INSERT INTO tblBank (bankID, bankName)
VALUES (1, 'Bank 1'),
(2, 'Bank 2'),
(3, 'Bank 3');
INSERT INTO tblTrans (transID, transDate, donationID, adminID)
VALUES (1, '2022-12-31', 1, 1),
(2, '2022-01-01', 2, 1),
(3, '2022-05-23', 3, 2),
(4, '2022-05-23', 4, 2),
(5, '2022-07-09', 5, 3),
(6, '2022-08-20', 6 4),
(7, '2022-12-27', 7,4);
Sample ERD Diagram
Expected Output
Example: 1, John, Doe, 1, 2022-12-31, 1, XY, Bank 1, 3B, OP.
Your WHERE 'Donor BGroup' IN (SELECT...) clause evaluates to WHERE false, because you don't have any rows with that value in tblPerson.bGroup. So, your SELECT statement's result set is empty.
It's hard to puzzle out your requirement from your question.
I managed to find the solution. Since I needed to call the same table twice with different IDs I had to create two aliases and JOIN the table twice, like so:
SELECT t.adminID, person.firstName, person.lastName, t.transID, t.transDate, t.donationID, person.bGroup, b.bankName, donor.personID AS 'Donor ID', donor.bGroup AS 'Donor BGroup'
FROM tblTrans t
JOIN tblAdmin a ON t.adminID = a.adminID
JOIN tblPerson person ON a.personID = person.personID
JOIN tblDonation d ON t.donationID = d.donationID
JOIN tblPerson donor ON
JOIN tblBank b ON d.bankID = b.bankID;
I have data as main table now how can I show data as per query table. Please help.
Hello Please test this:
CREATE TABLE MainTable
(
Code INT, ItemName VARCHAR(30), SalesDate DATETIME, SalesQty INT);
INSERT INTO MainTable VALUES
(1, 'Product-1','2022-01-01',593),
(2, 'Product-2','2022-01-02',1152),
(3, 'Product-3','2022-01-03',1629),
(4, 'Product-4','2022-01-04',4216),
(5, 'Product-5','2022-01-05',1760),
(1, 'Product-1','2022-02-01',1634),
(2, 'Product-2','2022-02-02',1748),
(3, 'Product-3','2022-02-03',2259),
(4, 'Product-4','2022-02-04',2076),
(5, 'Product-5','2022-02-05',1040);
SELECT Code, ItemName,
(CASE WHEN MONTH(SalesDate) = 1 THEN SUM(SalesQty) END) AS January,
(CASE WHEN MONTH(SalesDate) = 2 THEN SUM(SalesQty) END) AS February
FROM MainTable
GROUP BY Code, ItemName,SalesDate;
Result_Set:
Given the following data set, how would I find the email addresses that were references for the most ApplicationIDs that have an "Accepted" decision?
CREATE TABLE IF NOT EXISTS `EmailReferences` (
`ApplicationID` INT NOT NULL,
`Email` VARCHAR(45) NOT NULL,
PRIMARY KEY (`ApplicationID`, `Email`)
);
INSERT INTO EmailReferences (ApplicationID, Email)
VALUES
(1, 'ref10#test.org'), (1, 'ref11#test.org'), (1, 'ref12#test.org'),
(2, 'ref20#test.org'), (2, 'ref21#test.org'), (2, 'ref22#test.org'),
(3, 'ref11#test.org'), (3, 'ref31#test.org'), (3, 'ref32#test.org'),
(4, 'ref40#test.org'), (4, 'ref41#test.org'), (4, 'ref42#test.org'),
(5, 'ref50#test.org'), (5, 'ref51#test.org'), (5, 'ref52#test.org'),
(6, 'ref60#test.org'), (6, 'ref11#test.org'), (6, 'ref62#test.org'),
(7, 'ref70#test.org'), (7, 'ref71#test.org'), (7, 'ref72#test.org'),
(8, 'ref10#test.org'), (8, 'ref81#test.org'), (8, 'ref82#test.org')
;
CREATE TABLE IF NOT EXISTS `FinalDecision` (
`ApplicationID` INT NOT NULL,
`Decision` ENUM('Accepted', 'Denied') NOT NULL,
PRIMARY KEY (`ApplicationID`)
);
INSERT INTO FinalDecision (ApplicationID, Decision)
VALUES
(1, 'Accepted'), (2, 'Denied'),
(3, 'Accepted'), (4, 'Denied'),
(5, 'Denied'), (6, 'Denied'),
(7, 'Denied'), (8, 'Accepted')
;
Fiddle of same:http://sqlfiddle.com/#!9/03bcf2/1
Initially, I was using LIMIT 1 and ORDER BY CountDecision DESC, like so:
SELECT er.email, COUNT(fd.Decision) AS CountDecision
FROM EmailReferences AS er
JOIN FinalDecision AS fd ON er.ApplicationID = fd.ApplicationID
WHERE fd.Decision = 'Accepted'
GROUP BY er.email
ORDER BY CountDecision DESC
LIMIT 1
;
However, it occurred to me that I could have multiple email addresses that referred different "most accepted" decisions (i.e., a tie, so to speak), and those would be filtered out (is that the right phrasing?) with the LIMIT keyword.
I then tried a variation on the above query, replacing the ORDER BY and LIMIT lines with:
HAVING MAX(CountDecision)
But I realized that that's only half a statement: MAX(CountDecision) needs to be compared to something. I just don't know what.
Any pointers would be much appreciated. Thanks!
Note: this is for a homework assignment.
Update: To be clear, I'm trying to find value and count of Emails from EmailReferences. However, I only want rows that have FinalDecision.Decision = 'Accepted' (on matching ApplicantIDs). Based on my data, the result should be:
Email | CountDecision
---------------+--------------
ref10#test.org | 2
ref11#test.org | 2
For example...
SELECT a.*
FROM
( SELECT x.email
, COUNT(*) total
FROM emailreferences x
JOIN finaldecision y
ON y.applicationid = x.applicationid
WHERE y.decision = 'accepted'
GROUP
BY x.email
) a
JOIN
( SELECT COUNT(*) total
FROM emailreferences x
JOIN finaldecision y
ON y.applicationid = x.applicationid
WHERE y.decision = 'accepted'
GROUP
BY x.email
ORDER
BY total DESC
LIMIT 1
) b
ON b.total = a.total;
MySQL still lack window functions, but when version 8 is production ready, this becomes easier. So for fuure reference, or for those databases like Mariadb that already have window functions:
CREATE TABLE IF NOT EXISTS `EmailReferences` (
`ApplicationID` INT NOT NULL,
`Email` VARCHAR(45) NOT NULL,
PRIMARY KEY (`ApplicationID`, `Email`)
);
INSERT INTO EmailReferences (ApplicationID, Email)
VALUES
(1, 'ref10#test.org'), (1, 'ref11#test.org'), (1, 'ref12#test.org'),
(2, 'ref20#test.org'), (2, 'ref21#test.org'), (2, 'ref22#test.org'),
(3, 'ref30#test.org'), (3, 'ref31#test.org'), (3, 'ref32#test.org'),
(4, 'ref40#test.org'), (4, 'ref41#test.org'), (4, 'ref42#test.org'),
(5, 'ref50#test.org'), (5, 'ref51#test.org'), (5, 'ref52#test.org'),
(6, 'ref60#test.org'), (6, 'ref11#test.org'), (6, 'ref62#test.org'),
(7, 'ref70#test.org'), (7, 'ref71#test.org'), (7, 'ref72#test.org'),
(8, 'ref10#test.org'), (8, 'ref81#test.org'), (8, 'ref82#test.org')
;
CREATE TABLE IF NOT EXISTS `FinalDecision` (
`ApplicationID` INT NOT NULL,
`Decision` ENUM('Accepted', 'Denied') NOT NULL,
PRIMARY KEY (`ApplicationID`)
);
INSERT INTO FinalDecision (ApplicationID, Decision)
VALUES
(1, 'Accepted'), (2, 'Denied'),
(3, 'Accepted'), (4, 'Denied'),
(5, 'Denied'), (6, 'Denied'),
(7, 'Denied'), (8, 'Accepted')
;
select email, CountDecision
from (
SELECT er.email, COUNT(fd.Decision) AS CountDecision
, max(COUNT(fd.Decision)) over() maxCountDecision
FROM EmailReferences AS er
JOIN FinalDecision AS fd ON er.ApplicationID = fd.ApplicationID
WHERE fd.Decision = 'Accepted'
GROUP BY er.email
) d
where CountDecision = maxCountDecision
email | CountDecision
:------------- | ------------:
ref10#test.org | 2
dbfiddle here
I have a database of students.
CREATE TABLE classlist
(`id` int, `studentid` int, `subjectid` int, `presentid` int)
;
CREATE TABLE student
(`id` int, `name` varchar(4))
;
CREATE TABLE subject
(`id` int, `name` varchar(4))
;
CREATE TABLE classStatus
(`id` int, `name` varchar(8))
;
INSERT INTO classlist
(`id`, `studentid`, `subjectid`, `presentid`)
VALUES
(1, 111, 1, 1),
(2, 222, 3, 0),
(3, 333, 2, 1),
(4, 111, 4, 1),
(5, 111, 1, 0),
(6, 222, 3, 0),
(7, 333, 2, 1),
(8, 111, 4, 1),
(9, 111, 2, 0),
(10, 111, 4, 1),
(11, 111, 1, 1),
(12, 333, 3, 1),
(13, 333, 2, 1),
(14, 333, 3, 1)
;
INSERT INTO student
(`id`, `name`)
VALUES
(111, 'John'),
(222, 'Kate'),
(333, 'Matt')
;
INSERT INTO subject
(`id`, `name`)
VALUES
(1, 'MATH'),
(2, 'ENG'),
(3, 'SCI'),
(4, 'GEO')
;
INSERT INTO classStatus
(`id`, `name`)
VALUES
(0, 'Absent'),
(1, 'Present')
;
And I have a query which shows how many times they have been present or absent.
SELECT
studentid,
students.name AS NAME,
SUM(presentid = 1) AS present,
SUM(presentid = 0) AS absent
FROM classlist
INNER JOIN student as students ON classlist.studentid=students.id
GROUP BY studentid, NAME
See this fiddle below.
http://sqlfiddle.com/#!2/fe0b0/1
There seems to be a trend from looking at this sample data that after someone attends subjectid 4 they are often not coming to the next class. How can I capture this in a query. I want to ONLY show data WHERE last subjectid =4. So in my sample data rows matching my criteria would be.
(5, 111, 1, 0),
(9, 111, 2, 0),
(11, 111, 1, 1),
as these rows are all the next row of a studentid who had a subjectid=4.
My output would be
| STUDENTID | NAME | PRESENT | ABSENT|
| 111 | John | 1 | 2 |
To get the next class for a student, use a correlated subquery:
select cl.*,
(select min(cl2.id) from classlist cl2 where cl2.studentid = cl.studentid and cl2.id > cl.id) as nextcl
from classlist cl
Plugging this into your query example tell you you who is present and absent for the next class:
SELECT students.id, students.name AS NAME,
SUM(cl.presentid = 1) AS present, SUM(cl.presentid = 0) AS absent,
sum(clnext.presentid = 1) as presentnext
FROM (select cl.*,
(select min(cl2.id) from classlist cl2 where cl2.studentid = cl.studentid and cl2.id > cl.id) as nextcl
from classlist cl
) cl INNER JOIN
student as students
ON cl.studentid = students.id left outer join
classlist clnext
on cl.nextcl = clnext.id
GROUP BY students.id, students.NAME
Add a where cl.subjectid = 4 to get the answer for subject 4.
I fixed the query. The SQLFiddle is k.
A quick and dirty solution could be to get the Classlist.Id for all lines where subjectid=4 (let's call them n) then select all the lines where Id = n+1
I have two tables Like Below
CREATE TABLE projectlist(ProjectId INT NOT NULL PRIMARY KEY,
ProjectName VARCHAR(50),
Location VARCHAR(50));
CREATE TABLE LocationList(LocaId INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
ProjectId INT,
Location VARCHAR(50));
The Values in the table are as Below
INSERT INTO projectlist(ProjectId, ProjectName)
VALUES(1, 'Project A'),
(2, 'Project B'),
(3, 'Project C'),
(4, 'Project D'),
(5, 'Project E'),
(6, 'Project F'),
(7, 'Project G'),
(8, 'Project H');
INSERT INTO LocationList(ProjectId, Location)
VALUES(1, 'Location A'),
(1, 'Location C'),
(2, 'Location C'),
(2, 'Location B'),
(2, 'Location A'),
(3, 'Location B'),
(4, 'Location C'),
(5, 'Location D'),
(6, 'Location A'),
(6, 'Location B'),
(7, 'Location B'),
(8, 'Location D'),
(8, 'Location A');
I want a Insert Query which inserts First LocationList.Location into projectlist.Location for their respective project relating on project id.
So the table projectlist after running query is
ProjectName Location
Project A Location A
Project B Location C
Project C Location B
Project D Location C
Project E Location D
Project F Location A
Project G Location B
Project H Location D
I tried a SQL query which bring the First Location from LocationList table as below.
SELECT DISTINCT MNPCL.Location, MNP.ProjectId
FROM LocationList MNPCL RIGHT OUTER JOIN
projectlist MNP ON MNP.ProjectId = MNPCL.ProjectId
GROUP BY MNP.ProjectName
How to write a query which perform insert in the projectlist Location
Thanks For Reply
Here is a SQLFiddle demo
update projectlist
join
(
select LocationList.ProjectID,LocationList.Location
from LocationList
join
(select LocationList.ProjectID,min(LocaId) minLocaId
from LocationList
group by LocationList.ProjectID) l1
on LocationList.LocaId=l1.minLocaID
) l2 on projectList.ProjectID=l2.ProjectID
SET ProjectList.Location=l2.Location
try:
UPDATE projectlist AS prj SET Location =
(SELECT Location FROM LocationList AS lst WHERE lst.ProjectId = prjProjectId ORDER BY Location DESC LIMIT 1)
since your projects have more than one location in LocationList and you can only have one location in your projectlist table you have to limit the result set to one row.
This will work for you...
UPDATE projectlist AS prj SET Location = (
SELECT group_concat(locationlist.Location SEPARATOR ',') as loc FROM `locationlist` left join projectlist using (ProjectId)
group by locationlist.ProjectId)