I have four tables:
Table A: users_table
Table B: users_account_table
Table C: fangates_table
Table D: downloads_table
Table A(users_table) contains three columns: ID, NAME and GATE_COUNT.
Table C(fangates_table) contains users gates.
Table D(downloads_table) contains fangates_table_id and account_id.
TABLE A
ID | NAME | GATE_COUNT
---------------------------
1 | Joy | 2
---------------------------
2 | Ash | 0
---------------------------
3 | Nik | 2
---------------------------
4 | Wox | 0
TABLE B
ID | A_ID | ACCOUNT_ID
---------------------------
1 | 1 | 123456
---------------------------
2 | 1 | 654321
---------------------------
3 | 3 | 5888
---------------------------
4 | 3 | 8787
TABLE C
ID | A_ID | TITLE
---------------------------
1 | 1 | ABCD
---------------------------
2 | 1 | DFCV
---------------------------
3 | 3 | FGTG
---------------------------
4 | 3 | FRGTG
TABLE D
ID | C_ID | ACCOUNT_ID
---------------------------
1 | 1 | 123456
---------------------------
2 | 2 | 123456
---------------------------
3 | 3 | 7859
---------------------------
4 | 1 | 7585
From the above tables, I am trying to get the total "active" users (where an active user is defined as a user with fangates having any downloads other not themself)
I have tried the following query, but it has failed.
SELECT COUNT(*) FROM D
WHERE (C_ID,ACCOUNT_ID)
NOT IN
(SELECT C.ID, B.ACCOUNT_ID FROM A
LEFT JOIN B ON A.ID = B.A_ID
LEFT JOIN C ON A.ID = C.A_ID
WHERE A.GATE_COUNT >0);
The error, as I see it, is that you are failing to provide a join parameter in the initial selection of your table. If I am to understand your table design correctly, the following query would retrieve all the information in your tables:
SELECT *
FROM A,B,C,D
WHERE B.A_ID = A.ID AND C.A_ID = A.ID AND D.C_ID = C.ID;
If my presumption is correct, and you are trying to get the active users, you could simply place your parameters as an appended AND and continue onward. However, doing this many joins could greatly slow down any code; joins are a very taxing process, no matter how small the tables are. Since you are looking to find the count of downloads
SELECT COUNT(*) FROM D
WHERE (C_ID)
NOT IN
(SELECT C.ID FROM A, C
WHERE GATE_COUNT >0 AND A.ID = C.A_ID);
From what I can tell, you don't need to specify the distinct ACCOUNT_ID from the B table, as the information is distinctly paired to the B table. Otherwise, your columns would mismatch.
Otherwise, you can do a second lookup and try adding the B lookup as an AND parameter
SELECT COUNT(*) FROM D
WHERE (C_ID)
NOT IN (SELECT C.ID FROM A, C
WHERE GATE_COUNT >0 AND A.ID = C.A_ID) AND ACCOUNT_ID NOT IN
(SELECT DISTINCT B.ACCOUNT_ID FROM A,B WHERE A.ID = B.A_ID AND A.GATE_COUNT >0);
SELECT COUNT(DISTINCT(B.A_ID))
FROM TABLE_B B
JOIN TABLE_C C ON (B.A_ID = C.A_ID)
JOIN TABLE_D D ON (D.C_ID = C.C_ID AND B.ACCOUNT_ID <> D.ACCOUNT_ID)
Related
I am trying to write a MySQL query to select all rows from table a, as well as information from table b, while also querying the count and sum of values in another table c, for each row of a.
I will try to break that down a bit better, here is a simplified version of my tables:
Table A
+---------+----------+-----------+
| id | name | bid |
+---------+----------+-----------+
| 1 | abc | 1 |
| 2 | def | 1 |
| 3 | ghi | 2 |
+--------------------------------+
Table B
+---------+----------+
| id | name |
+---------+----------+
| 1 | STAN |
| 2 | UCLA |
+--------------------+
Table C
+---------+----------+-----------+
| id | aid | cnumber |
+---------+----------+-----------+
| 1 | 1 | 40 |
| 2 | 1 | 20 |
| 3 | 2 | 10 |
| 4 | 3 | 40 |
| 5 | 3 | 20 |
| 6 | 3 | 10 |
+--------------------------------+
What I need is a query that will return rows containing
a.id | a.name | b.id | b.name | SUM(c.cnumber) | COUNT(c.cnumber)
I am not sure if such a thing is even possible in MySQL.
My current solution is trying to query A + B Left Join and then UNION with A + C Right Join. It's not giving me the results I'm looking for however.
Thanks.
edit:
current query re-written for this problem:
SELECT
a.id,
a.name,
b.id,
b.name
"somecolumn" as dummy_column
"somecolumn1" as dummy_column1
FROM a
LEFT OUTER JOIN b ON a.b.id = b.id
UNION
SELECT
"somecolumn" as dummy_column
"somecolumn1" as dummy_column1
"somecolumn2" as dummy_column2
"somecolumn3" as dummy_column3
COUNT(c.cnumber) AS ccount
SUM(c.cnumber) AS sum
FROM a
RIGHT OUTER JOIN c ON a.id = c.a.id;
Unfortunately MySQL doesn't have FULL OUTER JOIN, and this is my temporary work around, although I don't think it's even the proper idea.
My desired output is all the rows from table A with some info from table B, as well as their totaled inputs in table C.
edit2:
SELECT
a.id,
a.name,
b.id,
SUM(c.cnumber) as totalSum,
(SELECT count(*) FROM c as cc WHERE cc.aid = a.id) as totalCount
FROM
a
LEFT JOIN b ON a.bid = b.id
LEFT JOIN c ON c.aid = a.id;
For future similar questions, solution:
SELECT
a.id AS aid,
a.name,
b.id,
(SELECT SUM(c.rating) FROM c WHERE c.aid = aid) AS totalSum,
(SELECT COUNT(c.rating) FROM c WHERE c.aid = aid) AS totalCount
FROM
a
LEFT JOIN b ON a.bid = b.id;
Your query should be :-
SELECT
a.id,
a.name,
b.id,
(SELECT SUM(c.cnumber) FROM c as cd WHERE cd.aid = a.id) as totalSum,
(SELECT count(*) FROM c as cc WHERE cc.aid = a.id) as totalCount
FROM
a
LEFT JOIN b ON a.bid = b.id
LEFT JOIN c ON c.aid = a.id;
It may help you.
I have tried your example.
SELECT * ,
(SELECT SUM(cnumber) FROM `table_c` WHERE `table_c`.`iaid` = `table_a`.`id`),
(SELECT COUNT(cnumber) FROM `table_c` WHERE `table_c`.`a.id` = `table_a`.`id`)
FROM `table_a`,`table_b` WHERE `table_b`.`id` = `table_a`.`b.id`
i got the Following output.
So, I have a table spiller with players and their id.
id | navn
-------------
1 | John Doe
2 | Matoma
3 | Lemaitre
4 | Koan
Secondly i have a table spillerpar that puts players in pairs. This table consist of an Auto inc id and the foreign key of spiller id x 2.
id | spiller_id_fk_1 | spiller_id_fk_2
--------------------------------------
1 | 1 | 4
2 | 3 | 2
Im trying to display the values of 2 fk's along with the fk id. I cant figure out how to. Please help.
select a.sid1, a.spiller1, b.sid2, spiller2
FROM
(Select 1_spillerpar.spiller_id_fk_1 as sid1, 1_spiller.navn as spiller1
From 1_spillerpar
Join 1_spiller
ON 1_spillerpar.spiller_id_fk_1 = 1_spiller.id) as a,
(Select 1_spillerpar.spiller_id_fk_2 as sid2, 1_spiller.navn as spiller2
From 1_spillerpar
Join 1_spiller
ON 1_spillerpar.spiller_id_fk_2 = 1_spiller.id) as b
EDIT
Desired output would look like:
id | spiller_id_fk_1 | navn | spiller_id_fk_2 | navn
--------------------------------------------------------
1 | 1 | John Doe| 4 | Koan
2 | 3 | Lemaitre| 2 | Matoma
Select s1.*,s2.* from spillerpar x
Join spiller s1 on s1.id = spiller_id_fk_1
Join spiller s2 on s2.id = spiller_id_fk_2
Spillerpar.id is redundant
Strawberry's answer works as expected I think. An alternative is:
SELECT sp.id as `pairId`, s1.*,s2.* FROM spillerpar sp, spiller s1, spiller s2
WHERE s1.id = sp.spiller_id_fk_1 AND s2.id = sp.spiller_id_fk_2
SQL fiddle here
(Edited fiddle to match fk names + added pairId)
I want to join 5 tables through book_id. I tried:
SELECT booked_room_info . * , booking_info . * , hotel_info.name as
hotelname,hotel_info.address as hoteladdress,hotel_info.contact as
hotelcontact , personal_info . *,room_registration.room_name as
roomname,room_registration.price as roomprice,room_registration.price as
roomprice,room_registration.description as
roomdescription,room_registration.image as roomimage
FROM booked_room_info
JOIN booking_info ON booking_info.booking_id = booked_room_info.booking_id
JOIN hotel_info ON hotel_info.id = booking_info.hotel_id
JOIN personal_info ON personal_info.booking_id = booked_room_info.booking_id
JOIN room_registration ON room_registration.hotel_id = booking_info.hotel_id
WHERE booked_room_info.booking_id= 1
But if i have 2 booking on booking_id = 1 but it fetched 10 result. I think I should make a if condition like. If (booked.room_type && book_info.hotel_id) is same then only fetch rows from room_registration but how can I aacomplish it.
booked_room_info
------
id | booking_id | room_type | check_in | check_out
1 | 1 | delux | 2015/1/2 | 2015/1/5
booking_info
---------
id | booking_id | hotel_id | user_id
1 | 1 | 2 | 1
hotel_info
----------
id | name | address | user_id
2 |palm hotel | newyork | 1
personal_info
-------------
id |full_name | address | nationality | booking_id
1 | sushil stha | new york | smth | 1
room_registration
-----------------
id | room_name | price | image | hotel_id | user_id
1 | delux | 1000 |room.jpg | 2 | 1
There is an error in your last join:
JOIN room_registration ON room_registration.hotel_id = booking_info.hotel_id
You are joining these tables using hotel_id column. There are probably 5 rows in room_registration table with hotel_id=2. So after joining you receive 2*5=10 rows instead of expected 2.
So you should join with this table in different way.
If you want to join every row with exacly one row from room_registration table then you have to specify more precise join condition.
To join room_registration table properly you may add room_registration_id column to booking_info table. Then you can join using:
JOIN room_registration ON room_registration.id = booking_info.room_registration_id
Use INNER JOIN's, removed the duplicate field.
SELECT
bri.*,
bi.*,
hi.name AS hotelname, hi.address as hoteladdress, hi.contact AS hotelcontact,
pi.*,
rr.room_name AS roomname, rr.price AS roomprice, rr.description AS roomdescription, rr.image AS roomimage
FROM booked_room_info bri
INNER JOIN booking_info bi ON bri.booking_id = bi.booking_id
INNER JOIN hotel_info hi ON bi.hotel_id = hi.id
INNER JOIN personal_info pi ON bri.booking_id = pi.booking_id
INNER JOIN room_registration rr ON bi.hotel_id = rr.hotel_id
WHERE bri.booking_id = 1
Simple problem. Given example tables:
Table A:
id | type
---+-----
1 | A
2 | B
3 | C
Table B:
id | a_id | type
---+------+-----
1 | 1 | X
2 | 2 | Y
3 | 1 | X
4 | 3 | Z
(there are additional columns, which I omitted, in order to clarify the problem)
The query:
SELECT a.*
FROM a a
INNER JOIN b b ON b.a_id = a.id
WHERE b.type = 'X'
Result:
id | type
---+-----
1 | A
1 | A
SQL Fiddle: http://sqlfiddle.com/#!2/e6138f/1
But I only want to have distinct rows of Table A. I know, I could do SELECT DISTINCT a.*, but our Table A has about 40 columns, and this SELECT can return 100-10000 rows. Isn't that extremely slow, if the database has to compare each column?
Or is MySQL intelligent enough, to just focus on the Primary Key for the DISTINCT operation?
Thanks in advance :)
Use exists instead of an explicit join:
select a.*
from tablea a
where exists (select 1 from tableb b where b.a_id = a.id and b.type = 'x');
For performance, create an index on tableb(a_id, type).
I have following two tables
table a->
Class_ID | name | class
1 | abc | a
1 | def | a
2 | ghi | b
2 | jkl | b
2 | mno | b
3 | pqr | c
3 | stu | c
table b->
Class_ID | class
1 | a
1 | a
2 | b
2 | b
3 | c
3 | c
I want the result to return 1 for CLASS_ID = 1 & 3 and 0 for CLASS_ID = 2, i.e. query should return 1 if number of rows in table a is equal to no of rows in table b.
select Class_ID, acount = bcount as count_matches
from (select Class_ID, COUNT(*) acount
from TableA
group by Class_ID) a
JOIN (select Class_ID, COUNT(*) acount
from TableB
group by Class_ID) b
USING (Class_ID)
Note that this query assumes that there are no missing class IDs in the tables. If just one of them can be missing some class_IDs, you can use a LEFT or RIGHT JOIN, depending on which it could be (and use IFNULL(Xcount, 0) for the count from that table). If either of them can be missing some, you need a FULL JOIN, but MySQL doesn't support it. If you search SO you can find the workaround solutions.
If you just want to do it for one class ID at a time, it's even simpler:
select (select count(*) from TableA where Class_ID = 1) =
(select count(*) from TableB where Class_Id = 1) as count_matches