mysql join tables and display fk values - mysql

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)

Related

How to get total "active" users using Mysql?

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)

Updating a MySQL table with a self-referencing column

I have a table (simplified) that looks like this:
id | name | selfreference | selfreference-name
------ | -------| --------------| ------------------
1 | Vienna | |
2 | Wien | | Vienna
3 | Виена | | Vienna
The selfreference column refers to the id numbers of the same table. In the above example, both Wien and Виена refer to the same city, so the value of their selfreference column should be equal to 1.
In other words, I need to do something like
update `places`
set `places`.`selfreference` =
(select `places`.`id` from `places`where `places`.`name` = `places`.`selfreference-name`)
but the SELECT statement above is obviously wrong. I am at a loss how to proceed.
Any tips would be greatly appreciated.
All best,
Tench
Edit: the desired output would look like this:
id | name | selfreference | selfreference-name
------ | -------| --------------| ------------------
1 | Vienna | |
2 | Wien | 1 | Vienna
3 | Виена | 1 | Vienna
Could be you need a self join
chekc with select
select a.*, b.*
from `places` as a
inner join `places` as b
where b.`name` = a.`selfreference-name`;
and then if the query above give you the right result
update `places` as a
inner join `places` as b
set b.`selfreference` = ab.`id`
where b.`name` = a.`selfreference-name`;
The following query does the job:
UPDATE places p1
INNER JOIN places p2 ON p1.`name` = p2.`selfreference-name`
SET p2.selfreference = p1.id;
p2 -> instance of table places which will be updated.
p1 -> instance of table places from where the id of the matching selfreference-name is taken.
WORKING DEMO BEFORE UPDATING
WORKING DEMO AFTER UPDATING

How to join 5 tables with IF conditions

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

TABLE 1 with name and surname and TABLE 2 with two columns reference to names on TABLE 1

I'm not a programmer and I read alot from this form about how to solve my question, but my search was no good
I have two tables
TABLE 1: members
id*| name | surname
-------------------
1 | Joe | Smith
2 | Mary | Sullivan
3 | Will | Stevenson
TABLE 2: messages
---------------------------------
id_message*| from | to | message
---------------------------------
1 | 2 | 1 | test
2 | 1 | 2 | re:test
3 | 3 | 1 | hi
*auto-increment fields
I wish to do a query where lists all the messages as shown below:
Mary Sullivan | Joe Smith | test
Joe Smith | Mary Sullivan | re:test
Will Stevenson | Joe Smith | hi
I'm really really really lost
Anyone can help? Thanks!
You need to join the members table 2 times with messages
select
concat(mem1.name,' ',mem1.surname) as `from_name`,
concat(mem2.name,' ',mem2.surname) as `to_name`,
m.message
from messages m
join members mem1 on mem1.id = m.`from`
join members mem2 on mem2.id = m.`to`
Try:
select from1.name+" "+from1.surname, to2.name+" "+to2.surname, message from table2
join table1 from1 on table2.`from` = table1.id
join table1 to2 on table2.`to` = table1.id
You need to write a Select with alias to refer members table 2 times:
SELECT CONCAT(M1.surname, ' ', M1.name) as FROM, CONCAT( M2.surname, ' ', M2.name) as TO FROM
members M1 INNER JOIN
messages M on M.from = M1.id
INNER JOIN messages M2 on M.to = M2.id

Get 1 if number of rows in one table is equal to number of rows in other table

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