Mysql parent child in same table - sql

I have following table layout (all in one table SQL):
user_id, user_id_parent, fname, lname, shopname
I want to be able to print out fname and lastname and show what shop name the user is related to via (user_id_parent(is refering to user_id, you could say that user_id is a kind of shopname id) ). If it is a normal useracount in this case, the shopname is empty.
I would guess I should use som kind of Join, but i don't know how to use it when it's in the same table...
Result something like:
John Doe, Relating to: Shop #1

I did this working SQL and guess what, Tada! :-)
Posting this, so it may help other guys trying to do the same thing.
SELECT e.`user_type` AS usertype, e.`fname` AS employee, m.`shopname` AS associated_to
FROM rw_users e
INNER JOIN rw_users m ON e.`user_id_parent` = m.`user_id`

Related

How to query in a way that relates a name to an ID and then using that ID to sum up what comes under that ID

I'm a student learning SQL. With querying, if you are given data that you have to relate to a primary key in the same table that will then be used to identify data in another table, how do you query that? I only want a push in the right direction because I don't want to copy and paste someone's code.
For example:
You are to find out how many staff are being managed by a manager and you are to find this by using the managers first and last name (which is not the primary key). The database is below. ManagerNo and StaffID are the same.
Branch (BranchNo, ManagerNo)
Staff (staffID, fName, lName, position, BranchNo)
Thank you for your time
You would use two joins:
select s.*
from staff s join
branch b
on s.BranchNo = b.BranchNo join
staff sm
on sm.staffId = b.ManagerNo
where sm.fname = ? and sm.lname = ?;

SQL Copy data from table to another and count value

I am stuck at the moment. I am creating a sports database in MS Access for our sports club and have the following question...
So what I have:
Tbl_Player (Player_ID, Firstname, Lastname, position, Min_Played, Goal, Assist, Yellow, Red)
Tbl_Player_Match (FK Tbl_Player_Player_ID, Min_Played, Goal, Assist, Yellow, Red).
What I need and strugling on is the following. When I add a match and data is being saved in tbl_Player_Match, I would need to have this saved in the "Summary" table which is Tbl_Player.
I cannot find the right syntax for this, should I create another temp table with the stats? Should I simply add an SQL code here?
Thanks a lot for your help.
Bob
I'd strongly suggest just using a query to pull the totals at run time:
SELECT ID
, Naam
, Achtenaam
, SUM(Goals) as Total
FROM Speler LEFT JOIN SpelerStats ON Speler.ID = SpelerStats.Speler
GROUP BY ID
, Naam
, Achtenaam
If you must add it to the table you'll have to use a domain aggregate function:
UPDATE Speler
SET Total = DSUM("Goals","SpelerStats","SpelerStats.Speler = " & Speler.ID)
I would tell you that you shouldn't store a summed value in tbl_Player. There comes only the characteristics of a Player for instance Name, Position and so on.
For the Output you create a query that would go something like this:
Select p.Player_ID, p.Firsname, p.Lastname, p.position, SUM(pm.Min_Played) as Sum_Min_Played
//, Count(pm.Tbl_Player_Match_ID) as Matches_Played
From
Tbl_Player p inner join Tbl_Player_Match pm on p.Player_ID = pm.Tbl_Player_Player_ID
group by p.Player_ID, p.Firsname, p.Lastname, p.position
The Matches_Played is just an addition, if you have sth. like an ID for the Matches Table.
Tell me if it helped you.

SQL multiplicity many to many insertion process

my question it seems to be pretty simple but unfortunately i couldn't find any satisfactory answer for this.
Please take a look on the following example:
Table Author define a author, Document has at least one author and table Authors group all authors that a document has.
My question is: Each time that i insert a document i need to verify if my group of authors exists already on table Authors.
What is the best way to do this?
I suppose that in first place i will need to verify if this group already exist and then, i should get that id (if already exist) or generate a new record on Authors (if group doesn't exist).
Question:
Is this the correct logic process that should occur on tables that has a multiplicity of many to many?
How can i check if a group of values already exist on table Authors??
There is something like this select * from Authors where a_id IN(1,2,3) but in a exclusive way. :S
Any help would be great.
Thanks
I would rather go with a solution with three tables:
Author
Document
rel_author_document
And rel_author_document will have a structure like:
author_fk
document_fk
You don't need to add a new group, but just to associate authors to a document.
In rel_author_document you can even add additional columns like role, if you need something like that.
With this approach you can have two documents with the same group of authors, but this won't kill you performances.
In case your question is for a homework assignment and you can't change table structure then:
Query the Authors table to see if you have a group of Author with the same number of author_id in the where condition, something like:
select count(1) cnt
from Authors
where a_id IN(1,2,3)
If cnt is different from the number of author_ids, then insert a new group
If cnt is equal then get the id of that group of Authors:
select ID
from Authors
where a_id = 1
or a_id = 2
or a_id = 3
group by 1
having count(1) = 3
If its a "many-to-many" relationship I believe the table structure you are looking for is:
Author (
a_id,
name,
birth_date,
domain)
Document (
d_id,
abstract,
year)
Auth_Doc (
a_id,
d_id
)
In terms of checking if there is already a group of authors, it depends n how you're displaying your data. If I was uploading a document and I wanted to check if a set of authors exist, I would do the following:
Say your data is stored as:
a_id | name
1 | john, jack, bob
SELECT * FROM Author WHERE name like '%john%'
I hope this helps,
Sohail

SQL Duplicate Rows

I am new to SQL and was wondering if anyone could help me solve my problem.
I have a table that contains information as follows:
firstname lastname group orderinggroup date
tim s A Facebook 6/4/13
tim s A Facebook 6/4/13
tim s A Facebook 6/4/13
dan d B Google 4/5/12
dan d B Google 4/5/12
Something like that. I want it to look like this
firstname lastname group orderinggroup date
tim s A Facebook 6/4/13
dan d B Google 4/5/12
Where there aren't duplicates for tim and dan. I tried using DISTINCT but that only makes one column distinct, and I actually have many people named Tim, Dan, Groups that are A/B, etc. I was wondering if there is a method to take the distinct of multiple roles, e.g., Distinct of firstname, lastname, group, orderinggroup, and date. Last names matter. Thanks!
You could really use the max() function to aggregate some of the columns and do something like this:
select
firstname,
lastname,
[group],
max(orderinggroup) as orderinggroup,
max([date]) as [date]
from (VALUES
('tim','s','A','Facebook','6/4/13'),
('tim','s','A','Facebook','6/4/13'),
('tim','s','A','Facebook','6/4/13'),
('dan','d','B','Google','4/5/12'),
('dan','d','B','Google','4/5/12')) as A (firstname,lastname,[group],orderinggroup,[date])
--replace this with your tablename
GROUP BY firstname, lastname, [group]
ORDER BY [group]
This is bad data and DISTINCT will work. DISTINCT is actually great for this.
SELECT DISTINCT * from table
Why even list columns unless there is direct manipulation or subqueries going on? There's not even a JOIN in your statement. Please tell me with a comment why DISTINCT does not work in this situation as you mention you've used it before.
DISTINCT checks each column for matching values, if it hits a value that doesn't match on record A from record B it will spit out record B also because it's distinct from A. Even if everything before it matches.
In your example:
firstname lastname group orderinggroup date
tim s A Facebook 6/4/13
tim s A Facebook 6/4/13
tim s A Facebook 6/4/13
dan d B Google 4/5/12
dan d B Google 4/5/12
Let's start with Tim. Every field is exactly the same. Therefore Distinct would collapse all these records into one row. Same for Dan. Now if the lastname is different in your actual database (which should be reflected in your example) then DISTINCT will not work. However, the premise of your question would need to change. You would need to discern what in fact you want to reflect in your data set. Do you want to ignore the last name? Do you want to consider it? These questions are pertinent. Group By works also, but is unnecessary as you're not doing aggregates. I hope this helps.
You can use below query:
SELECT firstname, lastname, group, orderinggroup, date
FROM tablename
GROUP BY firstname, lastname, group, orderinggroup, date
HAVING count(*) = 1;

Is there a way to select automatically the row pointed by an FK on a given table?

Today while writing one of the many queries that every developer in my company write every day I stumbled upon a question.
The DBMS we are using is Sql Server 2008
Say for example I write a query like this in the usual PERSON - DEPARTMENT db example
select * from person where id = '01'
And this query returns one row:
id name fk_department
01 Joe dp_01
The question is: is there a way (maybe using an addon) to make sql server write and execute a select like this
select * from department where id = 'dp_01'
only by for example clicking with the mouse on the cell containing the fk value (dp_01 in the example query)? Or by right click and selecting something like ("Go to pointed value")?
I hope I didn't wrote something stupid or impossible by definition
Not really, but that seems like a silly thing to do. Why would you want to confuse an id with a department name?
Instead, you could arrange things so you could do:
select p.*
from person p
where department = 'dp_01';
You would do this by adding a computed column department that references a scalar function that looks up the value in the department table. You can read about computed columns here.
However, a computed column would have bad performance characteristics. In particular, it would basically require a full table scan on the person table, even if that is not appropriate.
Another solution is to create a view, v_person that has the additional columns you want. Then you would do:
select p.*
from v_person p
where department = 'dp_01';
Why can't you write yourself by saying
select * from department where id =
(select fk_department from person where id = '01')