I am not able to get data using the join query with 3Th table.
Table p:
- id
- name
Table s:
- id
- name
- description
Table ps:
- p_id
- s_id
$stmt = $this->conn->prepare("SELECT p.id, p.name FROM p, ps WHERE p.id = 1 AND ps.p_id = 1 AND ps.s_id = 1");
Here's the error: Call to a member function execute() on a non-object
Thanks
Two question:
(1) Have you tried running your query directly from the MySQL command line? And if so does it give you your desired result?
(2) Could you show more of your code. Perhaps the problem located some where else in your code.
For a start try this explicit JOIN query:
SELECT p.id, p.name
FROM p
JOIN ps
ON p.id = ps.p_id
JOIN s
ON ps.s_id = s.id
WHERE s.id = 1;
Sample data:
CREATE TABLE p
(
id int auto_increment primary key,
name varchar(20)
)ENGINE=InnoDB;
INSERT INTO p
(name)
VALUES
('Bob'),
('Jack'),
('John');
CREATE TABLE s
(
id int auto_increment primary key,
name varchar(30)
)ENGINE=InnoDB;
INSERT INTO s
(name)
VALUES
('blablabla'),
('Foo'),
('Foobar');
CREATE TABLE ps
(
id int auto_increment primary key,
p_id int,
s_id int,
FOREIGN KEY (p_id) REFERENCES p(id),
FOREIGN KEY (s_id) REFERENCES s(id)
)ENGINE=InnoDB;
INSERT INTO ps
(p_id,s_id)
VALUES
(1,1),
(1,2),
(2,1),
(2,2),
(3,2);
SQLFiddle demo
Related
I am new to SQL and I am running into trouble.
I have 3 tables:
CREATE TABLE indexCodes
{
(indexNum VARCHAR(5) PRIMARY KEY,
courseString VARCHAR(10),
title VARCHAR(20)
}
CREATE TABLE user
{
(id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
email VARCHAR(255) NOT NULL,
password VARCHAR(255) NOT NULL)
}
CREATE TABLE snipes
{
(snipeNumber INT NOT NULL PRIMARY KEY AUTO_INCREMENT),
FOREIGN KEY indexNum REFERENCES indexcodes(indexNum),
FOREIGN KEY userID REFERENCES user(id)
}
and inserting into snipes with
INSERT INTO snipes(indexNum, userID) VALUES ("06666", 1);
INSERT INTO snipes(indexNum, userID) VALUES ("06675", 1);
When I run
SELECT * FROM snipes, user, indexcodes where id=1
two indexNum columns appear with two different values, I am assuming that the snipes indexNum column shows whatever was inserted but the indexCodes indexNum displays a different result (I believe it is the first two entries in indexCodes)
When you put all the tables in the FROM clause divided only by comma without any restrictions of joining the tables with a WHERE clause you get a cartesian product of all the tables referenced in the FROM clause, for example, or using JOIN syntax instead of putting all the tables int the FROM clause. Here is two examples that would work on your scenario:
WHERE clause
SELECT * FROM snipes s, t_user u, indexcodes i where
s.indexNum = i.indexnum
and s.userid = u.id
and id=1;
JOIN syntax
SELECT * FROM snipes s
inner join t_user u on s.userid = u.id
inner join indexcodes i on s.indexNum = i.indexnum
where id=1;
Personally, I prefer to use the join syntax, it's a cleaner way to see the query.
I am trying to get the user first name with the most comments. How can I do this?
Here are the tables.
The tables below are the setup for the database tables which I am trying to query.
CREATE TABLE User(
userid varchar(3),
firstname varchar(20),
lastname varchar(20),
age int,
PRIMARY KEY(userid)
)ENGINE=INNODB;
CREATE TABLE Comment(
commentid varchar(3),
userid varchar(3),
eventid varchar(3),
title varchar(20),
comment varchar(50),
PRIMARY KEY(commentid),
FOREIGN KEY(userid) REFERENCES AnonymousUser(userid),
FOREIGN KEY(eventid) REFERENCES Event(eventid)
)ENGINE=INNODB;
INSERT INTO User VALUES('U01','Charles','Darwin',99);
INSERT INTO User VALUES('U02','Keisha','Strawn',24);
INSERT INTO User VALUES('U03','Denise','Malcolm',59);
INSERT INTO User VALUES('U04','Dennis','Stewart',19);
INSERT INTO User VALUES('U05','Robert','Johns',45);
INSERT INTO User VALUES('U06','Marsha','Stewart',33);
INSERT INTO Comment VALUES ('C01','A01','E01','Boring Event','This event was boring');
INSERT INTO Comment VALUES ('C02','A02','E01','Nice Nice Event','This event was Nice');
INSERT INTO Comment VALUES ('C03','A03','E03','Wow','This event was Amazing');
INSERT INTO Comment VALUES ('C04','A01','E01','Very Sad','I missed this event');
The query I tried is
SELECT User.userid FROM User
JOIN comment ON comment.userid = user.userid
WHERE (SELECT COUNT(comment)
FROM comment = (SELECT MAX(userid) FROM comment);
SELECT
userid
FROM
comment
GROUP BY userid
ORDER BY count(userid) DESC
LIMIT 1;
Edit: oh, you need the username. Try this:
SELECT firstname
FROM user
WHERE userid = (
SELECT
userid
FROM
comment
GROUP BY userid
ORDER BY count(userid) DESC
LIMIT 1
);
Query to get firstname with most comments is
select a.firstname, max(a.comment_count) from (
select u.firstname, count(c.commentid) comment_count
from user u join comment c on u.userid = c.userid
group by u.firstname
)a;
That said, I noticed
One of the constraints on table 'comment' is pointing to a table 'AnonymousUser' FOREIGN KEY(userid) REFERENCES AnonymousUser(userid). You have not shared the create table statement for that table.
I had to remove this constraint from table definition in order to successfully create this table in my database
CREATE TABLE Comment(
commentid varchar(3),
userid varchar(3),
eventid varchar(3),
title varchar(20),
comment varchar(50),
PRIMARY KEY(commentid)
);
You dataset for table 'comment' has no userid matching 'user.userid' values
I updated the 'comment' table inserts so I could get some result when executing my query.
INSERT INTO Comment VALUES ('C01','U01','E01','Boring Event','This event was boring');
INSERT INTO Comment VALUES ('C02','U01','E01','Nice Nice Event','This event was Nice');
INSERT INTO Comment VALUES ('C03','U03','E03','Wow','This event was Amazing');
INSERT INTO Comment VALUES ('C04','U06','E01','Very Sad','I missed this event');
EDIT: The isssue was mismatching data the B-ids in tables A_B and B_C had no overlap
I have the following tables:
A(id, …)
A_B(a_id, b_id)
B_C(b_id, c_id)
C_D(c_id, d_id)
D(id, value, …)
Where I want some rows from A based on the value of the row in D.
The tables A_B, B_C and C_D are just id mappings from one table to another.
I was trying to get to something that would look something like this:
select * from A where D.value = "true"
I got this far:
select * from A
inner join A_B on A_B.a_id = A.id
inner join B_C on B_C.b_id = A_B.b_id
which is just an empty table.
I am starting to think that I am approaching this issue in the wrong way or perhaps have misunderstood how one should go about joining tables.
What you've got works OK if your data is coherent. Here's a version of your database and query which demonstrates that. For simplicity, I inferred the existence of tables b and c, and made the various columns in the X_Y style tables into foreign keys to the single-letter tables.
CREATE TABLE a
(
id INTEGER NOT NULL PRIMARY KEY,
info VARCHAR(20) NOT NULL
);
CREATE TABLE b
(
id INTEGER NOT NULL PRIMARY KEY,
data VARCHAR(20) NOT NULL
);
CREATE TABLE C
(
id INTEGER NOT NULL PRIMARY KEY,
extra VARCHAR(20) NOT NULL
);
CREATE TABLE d
(
id INTEGER NOT NULL PRIMARY KEY,
value VARCHAR(20) NOT NULL
);
CREATE TABLE a_b
(
a_id INTEGER NOT NULL REFERENCES a,
b_id INTEGER NOT NULL REFERENCES b,
PRIMARY KEY (a_id, b_id)
);
CREATE TABLE b_c
(
b_id INTEGER NOT NULL REFERENCES b,
c_id INTEGER NOT NULL REFERENCES C,
PRIMARY KEY(b_id, c_id)
);
CREATE TABLE c_d
(
c_id INTEGER NOT NULL REFERENCES C,
d_id INTEGER NOT NULL REFERENCES d,
PRIMARY KEY(c_id, d_id)
);
INSERT INTO a VALUES(1, "Quasimodo");
INSERT INTO b VALUES(20, "Quiet");
INSERT INTO C VALUES(333, "Contemporaneous");
INSERT INTO d VALUES(4444, "true");
INSERT INTO a_b VALUES(1, 20);
INSERT INTO b_c VALUES(20, 333);
INSERT INTO c_d VALUES(333, 4444);
SELECT *
FROM a
JOIN a_b ON a_b.a_id = a.id
JOIN b_c ON b_c.b_id = a_b.b_id
JOIN c_d ON c_d.c_id = b_c.c_id
JOIN d ON d.id = c_d.d_id
WHERE d.value = "true";
For the given data, that produces:
1 Quasimodo 1 20 20 333 333 4444 4444 true
So, if the data is correct, the query you were building can produce an answer. However, if you were getting an empty table on your incomplete query, then there is a data problem in your tables — or (outside chance) your outline schema misled us.
Testing performed on a Mac running macOS High Sierra 10.13.4, using Informix 12.10.FC6, but using what is believed to be a subset of SQL common to Informix and MySQL.
I created a database with following tables :
CREATE SCHEMA IF NOT EXISTS `facturatiedatabase` ;
USE `facturatiedatabase` ;
DROP TABLE IF EXISTS tblAddress ;
DROP TABLE IF EXISTS tblContact ;
DROP TABLE IF EXISTS tblCustomers ;
CREATE TABLE tblCustomers (
customerID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
firstname VARCHAR(30) NOT NULL,
lastname VARCHAR(30) NOT NULL,
vat VARCHAR(30) NOT NULL,
customerVisible varchar(1) NOT NULL DEFAULT 'T'
) ENGINE=InnoDB;
CREATE TABLE tblContact (
contactID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
email VARCHAR(100),
phone VARCHAR(100),
customerID int,
CONSTRAINT FK_customerID_Contact FOREIGN KEY (customerID) REFERENCES tblCustomers(customerID)
) ENGINE=InnoDB;
CREATE TABLE tblAddress (
addressID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
street VARCHAR(100),
houseNumber VARCHAR(15),
city VARCHAR (100),
country VARCHAR (100),
customerID int,
CONSTRAINT FK_customerID_Adress FOREIGN KEY (customerID) REFERENCES tblCustomers(customerID)
) ENGINE=InnoDB;
INSERT INTO tblCustomers (firstname, lastname,vat)
VALUES ("John","Doe","UV45856855");
INSERT INTO tblContact (customerID,phone, email)
VALUES ((SELECT DISTINCT LAST_INSERT_ID() FROM tblCustomers), "0000001","Johndoe#gmail.com");
INSERT INTO tblAddress (customerID,street,housenumber,city,country)
VALUES ((SELECT DISTINCT LAST_INSERT_ID() FROM tblCustomers), "berkenlaan","1a","Harelbeke","Belgie");
But when i try following inner join it gives me the following error :
LIMIT 0, 1000 Error Code: 1052. Column 'customerID' in field list is ambiguous 0.000 sec.
SELECT customerID, firstname, lastname, vat,email
FROM tblCustomers
INNER JOIN tblContact on tblCustomers.customerID = tblContact.contactID
The error message says it all: the column name customerID is contained in both tables. So which value should mysql select? That is ambiguous, therefore the error.
Have a try with this variant:
SELECT tblCustomers.customerID AS customerID, firstname, lastname, vat,email
FROM tblCustomers
INNER JOIN tblContact on tblCustomers.customerID = tblContact.contactID
(or pick that other tables's column with the same if you need that one...)
And, frankly, I doubt your ON clause is the one you want to use. Shouldn't that be ON tblCustomers.customerID = tblContact.customerID instead?
I have a query against two databases that I'm trying to execute. The first table is just user information and is referenced by a privilege table. For my query I'm trying to find a set of super users, they are users that have every current privilege in the privilege table. It is set up as follows:
create table MEMBER
( id int not null,
name varchar(10),
bdate date,
sex char,
pc_id int not null,
PRIMARY KEY (mid),
FOREIGN KEY (pc_id) REFERENCES PLEDGECLASS(id))
create table MEMBER_PRIVILEGE
( mid int not null,
pid int not null,
PRIMARY KEY (mid,pid),
FOREIGN KEY (mid) REFERENCES MEMBER(id),
FOREIGN KEY (pid) REFERENCES PRIVILEGE(id))
create table PRIVILEGE
( id int,
pname varchar(15)
PRIMARY KEY(id))
Although obviously the incorrect query, I'm trying to do something equivalent to the following:
Select name
From MEMBER,MEMBER_PRIVILEGE
Where id=mid AND pid = ALL (select id
From PRIVILEGE);
SELECT *
FROM MEMBER
WHERE NOT EXISTS (
SELECT *
FROM MEMBER_PRIVILEGE LEFT JOIN PRIVILEGE ON MEMBER_PRIVILEGE.pid = PRIVILEGE.id)
WHERE MEMBER_PRIVILEGE.mid = MEMBER.id AND PRIVILEGE.id IS NULL
)
Try this ::
Select name, (select count(id) from PRIVILIGE) as p_count
From MEMBER m
inner join MEMBER_PRIVILEGE mp on (m.id=mp.mid)
group by mp.mid having count(*) = p_count;