query confusion create query without create view - mysql

Here is the question
we have 3 database variable(Person, event,invited)
Person(pid,passwd,fname,lname),
Event(eid, start_time,duration,description,pid)
Invited(pid,eid,response,visibility)
I want to make a query witch will do
show all people each event user X create.
For example Person David create the event with eid= 1 and 3. (2events)
and if Jany and Will invited to the eid =1 , and Mike invited to event 3
it should show
EID PID
1 Jany
1 will
3 mike
The part I confused is Person and Event 's PID is a creater of the event
and invited's PID is for person who invited. so its different PID value.
so i can not just natural join them
I can solve this problem with create view mysql command but I'm writing this code
on PHP form so I want to finish this command in one command.
what i tried is this
select *
from invited
where eid
in (SELECT eid
from person natural join event
where pid = 'DD')
But it does not give what I expected.
How to write the code in One command without 'create view' command for this problem?

Are you looking for this?
SELECT e.eid, i.pid, p.fname
FROM event e JOIN invited i
ON e.eid = i.eid JOIN person p
ON i.pid = p.pid
WHERE e.pid = ?
Sample output:
| EID | PID | FNAME |
|-----|-----|-------|
| 1 | 2 | Jany |
| 1 | 3 | Will |
| 3 | 4 | Mike |
Here is SQLFiddle demo
Recommended reading
A Visual Explanation of SQL Joins

Related

Issue with mysql query that calls column name from another table

I have two tables, one is an index (or map) which helps when other when pulling queries.
SELECT v.*
FROM smv_ v
WHERE (SELECT p.network
FROM providers p
WHERE p.provider_id = v.provider_id) = 'RUU='
AND (SELECT p.va
FROM providers p
WHERE p.provider_id = v.provider_id) = 'MjU='
LIMIT 1;
Because we do not know the name of the column that holds the main data, we need to look it up, using the provider_id which is in both tables, and then query.
I am not getting any errors, but also no data back. I have spent the past hour trying to put this on sqlfiddle, but it kept crashing, so I just wanted to check if my code is really wrong, hence the crashing?
In the above example, I am looking in the providers table for column network, where the provider_id matches, and then use that as the column on smv.
I am sure i have done this before just like this, but after the weekend trying I thought i would ask on here.
Thanks in Advance.
UPDATE
Here is an example of the data:
THis is the providers, this links so no matter what the name of the column on the smv table, we can link them.
+---+---+---------------+---------+-------+--------+-----+-------+--------+
| | A | B | C | D | E | F | G | H |
+---+---+---------------+---------+-------+--------+-----+-------+--------+
| 1 | 1 | Home | network | batch | bs | bp | va | bex |
| 2 | 2 | Recharge | code | id | serial | pin | value | expire |
+---+---+---------------+---------+-------+--------+-----+-------+--------+
In the example above, G will mean in the smv column for recharge we be value. So that is what we would look for in our WHERE clause.
Here is the smv table:
+---+---+-----------+-----------+---+----+---------------------+-----+--+
| | A | B | C | D | E | F | value | va |
+---+---+-----------+-----------+---+----+---------------------+-----+--+
| 1 | 1 | X2 | Home | 4 | 10 | 2016-09-26 15:20:58 | | 7 |
| 2 | 2 | X2 | Recharge | 4 | 11 | 2016-09-26 15:20:58 | 9 | |
+---+---+-----------+-----------+---+----+---------------------+-----+--+
value in the same example as above would be 9, or 'RUU=' decoded.
So we do not know the name of the rows, until the row from smv is called, once we have this, we can look up what column name we need to get the correct information.
Hope this helps.
MORE INFO
At the point of triggering, we do not know what the row consists of the right data because some many of the fields would be empty. The map is there to help we query the right column, to get the right row (smv grows over time depending on whats uploaded.)
1) SELECT p.va FROM providers p WHERE p.network = 'Recharge' ;
2) SELECT s.* FROM smv s, providers p WHERE p.network = 'Recharge';
1) gives me the correct column I need to look up and query smv, using the above examples it would come back with "value". So I need to now look up, within the smv table, C = Recharge, and value = '9'. This should bring me back row 2 of the smv table.
So individually both 1 and 2 queries work, but I need them put together so the query is done on the database server.
Hope this gives more insight
Even More Info
From reading other posts, which are not really doing what I need, i have come up with this:
SELECT s.*
FROM (SELECT
(SELECT p.va
FROM dh_smv_providers p
WHERE p.provider_name = 'vodaphone'
LIMIT 1) AS net,
(SELECT p.bex
FROM dh_smv_providers p
WHERE p.provider_name = 'vodaphone'
LIMIT 1) AS bex
FROM dh_smv_providers) AS val, dh_smv_ s
WHERE s.provider_id = 'vodaphone' AND net = '20'
ORDER BY from_base64(val.bex) DESC;
The above comes back blank, but if i replace net, in the WHERE clause with a column I know exists, I do get the results expected:
SELECT s.*
FROM (SELECT
(SELECT p.va
FROM dh_smv_providers p
WHERE p.provider_name = 'vodaphone'
LIMIT 1) AS net,
(SELECT p.bex
FROM dh_smv_providers p
WHERE p.provider_name = 'vodaphone'
LIMIT 1) AS bex
FROM dh_smv_providers) AS val, dh_smv_ s
WHERE s.provider_id = 'vodaphone' AND value = '20'
ORDER BY from_base64(val.bex) DESC;
So what I am doing wrong, which is net, not showing the value derived from the subquery "value" ?
Thanks
SELECT
v.*,
p.network, p.va
FROM
smv_ v
INNER JOIN
providers p ON p.provider_id = v.provider_id
WHERE
p.network = 'RUU=' AND p.va = 'MjU='
LIMIT 1;
The tables talk to each other via the JOIN syntax. This completely circumvents the need (and limitations) of sub-selects.
The INNER JOIN means that only fully successful matches are returned, you may need to adjust this type of join for your situation but the SQL will return a row of all v columns where p.va = MjU and p.network = RUU and p.provider_id = v.provider_id.
What I was trying to explain in comments is that subqueries do not have any knowledge of their outer query:
SELECT *
FROM a
WHERE (SELECT * FROM b WHERE a)
AND (SELECT * FROM c WHERE a OR b)
This layout (as you have in your question) is that b knows nothing about a because the b query is executed first, then the c query, then finally the a query. So your original query is looking for WHERE p.provider_id = v.provider_id but v has not yet been defined so the result is false.

Mysql query to search between two tables with no direct relationship

OK i found myself in a dead end, and i know must be a way but my brain is just about to explode. This is the case: I have two tables with tons of rows, one for works done (lets call it works table), something like this:
ID | Home_Work_ID | task_id | Person_id
1 | 23 | 1 | 30
2 | 23 | 2 | 31
3 | 23 | 3 | 30
4 | 876 | 1 | 31
5 | 123 | 3 | 32
and another table to report the fixes to do on the works mentioned before, lets call it fixes table
ID | Home_Work_ID | Person_reporting_id | Task_id | Details
1 | 23 | 93 | 1 | Fix this
2 | 23 | 85 | 3 | Fix that
3 | 123 | 86 | 3 | Fix something
As we can see, in the fixes table there are home works with fixes reported, and those home works was done by the person_id 30 and 32 (from the work table). The results that im trying to achieve would be:
Person | Fixes
John (lets say this is person id 30) | 2
Kate (lets say this is person id 32) | 1
The problem is, i need to create a report that show me who was the person responsable of the work done in the works table that have reported fixes in the second table and how many fixes was reported for that person. The only link is the home work id and probably the task id, so i was testing something like this
SELECT P.person_name AS Person, COUNT(F.id) AS fixes
FROM fixes F
INNER JOIN homeworks H ON F.home_work_id = H.id
INNER JOIN works as W
INNER JOIN people AS P ON W.person_id = P.id
INNER JOIN tasks AS T ON T.task_id = F.task_id
WHERE F.task_id = W.task_id
AND F.home_work_id = W.home_work_id
AND W.home_work_id IN (SELECT home_work_id FROM fixes GROUP BY home_work_id)
GROUP BY P.person_name ORDER BY fixes DESC
Ok there are three more inner/left joinable tables with the id and name of the person, home work and task. This show me the person responsable but the number of fixes for that person and that home_work/task dont match the ones in the fixes table, i guess im doing wrong inner joining the work table that way but i dont see the light yet. Any help will be really appreciated.
Regards
I think this query should give you the expected result:
SELECT P.Person_name AS Person, COUNT(F.id) AS fixes
FROM works W
INNER JOIN fixes F ON W.home_work_id = F.home_work_id and W.task_id=F.Task_id
INNER JOIN people P ON W.person_id = P.id
group by P.Person_name
however because I didn't read the question deeply, so I'm not sure
100% this will give exact result.
EDIT: question owner wrote the exact query of answer below.
Note from owner of the answer: Check the query, its based on it but not the "exact" query.
Ok after do some tests and thanks to the comments from Farhang Amary and Rick James from dba.stackexchange, the following query seems to do the job, so im posting it here for anyone that find itself on the same situation or for anything tha can be fixed on it:
SELECT P.Person_name AS Person, COUNT(F.id) AS fixes
FROM (SELECT person_id, home_work_id, task_id FROM work) W
LEFT JOIN fixes_table F ON W.home_work_id = F.home_work_id AND W.task_id = F.taks_id
LEFT JOIN People_table P ON W.person_id = P.id
GROUP BY P.person_name ORDER BY fixes DESC;

How can I get connected values of two times the same foreign key?

I currently have a situation that could easily be solved with 3 SQL queries, but I wonder if it can be done in one query.
I have the following tables:
symbol similarity
------- ------------
id | name | latex id | base_symbol_id | similar_symbol_id
I want to SELECT so that my result looks like this:
query_result
------------
similarity_id | base_formula_id | base_formula_name | base_formula_latex | similar_formula_id | similar_formula_name | similar_formula_latex
Failed tries
I usual solve similar tasks with JOIN. But this time, the SELECT depends on another attribute I select ... I don't know how to do this. Here is my try (which of course failed):
SELECT `base_symbol_id`, `similar_symbol_id`, `latex`
FROM `similarity`
JOIN `symbol` ON ((`symbol`.`id` = `base_symbol_id`) OR (`symbol`.`id` = `similar_symbol_id`))
gives
base_symbol_id | simlar_symbol_id | latex
10 | 11 | \alpha
10 | 11 | a
select sim.id
,base.id
,base.name
,base.latex
,similar.id
,similar.name
,similar.latex
from similarity as sim
join symbol as base on base.id=sim.base_symbol_id
join symbol as similar on similar.id=sim.similar_symbol_id
Using the given table structure, and making up some random sample inputs in an SQL Fiddle session, the following query would work as you desired:
SELECT T.id as similarity_id,
S1.id as base_formula_id, S1.name as base_formula_name, S1.latex as base_formula_latex,
S2.id as similar_formula_id, S2.name as similar_formula_name, S2.latex as similar_formula_latex
FROM similarity T
LEFT OUTER JOIN symbol S1 ON (T.base_symbol_id = S1.id)
LEFT OUTER JOIN symbol S2 ON (T.similar_symbol_id = S2.id)

select statement with only rows which have set true in second table

i have two tables
activity
id | user_id | time | activity_id
1 | 1 | | 3
2 | 1 | | 1
and preferences
user_id | running | cycling | driving
1 | TRUE | FALSE | FALSE
i need result set of
id | user_id | time |
2 | 1 | |
i only need rows from first table whose values are set true in preferences table.
e.g activity_id for running is 1 which is set true in preferences table, so it returns while others doesn't.
If you can edit the schema, it would be better like this:
activity
id | name
1 | running
2 | cycling
3 | driving
user_activity
id | user_id | time | activity_id
1 | 1 | | 3
2 | 1 | | 1
preferences
user_id | activity_id
1 | 1
A row in preferences indicates a TRUE value from your schema. No row indicates a FALSE.
Then your query would simply be:
SELECT ua.id, ua.user_id, ua.time
FROM user_activity ua
JOIN preferences p ON ua.user_id = p.user_id
AND ua.activity_id = p.activity_id
If you want to see the activity name in the results:
SELECT ua.id, ua.user_id, ua.time, activity.name
FROM user_activity ua
JOIN preferences p ON ua.user_id = p.user_id
AND ua.activity_id = p.activity_id
JOIN activity ON ua.activity_id = activity.id
What I would probably do is join the tables on a common column, looks like user_id is a common column in this case, which gives access to the columns in both tables to query against in the where clause of the query.
Which type of join depends on what information you want from preferences
Handy Visual Guide for joins
So you could query
SELECT * FROM activity LEFT JOIN preferences ON activity.user_id = preferences.user_id WHERE preferences.columnIWantToBeTrue = true
I'm using left join since you mentioned you want the values from the first table based on the second table.
Mike B has the right answer. The relational model relates rows together by common values.
You've got a table named activity with an id column which looks like the primary key. The column name activity_id would typically be the name of a column in another table that is a foreign key to the activity table, referencing activity.id.
It looks like you've used the activity_id column in the activity table as a reference to either "running", "cycling" or "driving".
It's possible to match activity.activity_id = 1 with "running", but this is a bizarre design.
Here's an example query:
SELECT a.id
, a.user_id
, a.time
FROM activity a
JOIN preferences p
ON p.user_id = a.user_id
AND ( ( p.running = 'TRUE' AND a.activity_id = 1 )
OR ( p.cycling = 'TRUE' AND a.activity_id = 2 )
OR ( p.driving = 'TRUE' AND a.activity_id = 3 )
)
But, again, this is a bizarre design.
As a start, each table in your database should have rows that represent either an entity (a person, place, thing, concept or event that can be uniquely identified, is important, and we need to store information about), or a relationship between the entities.
From the limited information we have about your use case, the entities appear to be "user", an "activity_type" (running, cycling, driving), an "activity" (an amount of time, for a user and an activity_type) and some user "preference" about which activity_types the user prefers.
See the answer from Mark B for a possible schema design.

LEFT JOIN and NOT ISSET

I have two table:
Site:
id | name
1 | google
2 | stackoverflow
3 | cnn.com
Confirm:
id | site_id | type // (type = 1, 2 or 3)
1 | 1 | 2
2 | 2 | 1
so and would like get Sites which is not added to table Confirm with type for example 1.
SELECT *
FROM Site
LEFT JOIN Confirm
ON Site.id = Confirm.site_id
and what next?
A natural way to write this query is as a NOT EXISTS query:
SELECT s.*
FROM Sites s
WHERE NOT EXISTS (SELECT 1 FROM Confirm c WHERE c.site_id = s.id AND type = 1);
It is almost a 1-1 translation of the problem statement: "would like to get sites that are not added to Confirm with type = 1".
I do not understand what you meant. But if you are in doubt about how to work with result sets from the database, look at this, maybe it can help you: http://www.codeproject.com/KB/database/Visual_SQL_Joins/Visual_SQL_JOINS_orig.jpg