Retrieving management hierarchy report from db - php

I need to prepare report that returns for each of our employee complete list of their higher ups.
I have two mariadb tables: employee and position
employee:
id, name, first_boss_id, position_id,
position:
id, position_name
Employee table contains all employees from juniors to top managers, but every entry contains only name of employee and his closest boss in hierarchy. How can I get all of the managers above him? I've got this so far:
SELECT e.id, e.name, p.position_name, b.name,
FROM employee e
LEFT JOIN employee b ON e.firts_boss_id = b.id
LEFT JOIN position p ON e.position_id = p.id
It returns id, name of employee, his carrier position and name of his closest manager/boss. How can I get names of the rest of higher management for this employee? Is it better to use SQL query or write some PHP script to create that report from data I get from query above?
Either way I could really use some pointers how to get it done. Thank you!

Related

Getting data from 2 tables with relationship with WHERE clausule

I've been following the PHP Authentication Tutorial en managed to get it working.
Now I want to add a function to my navbar. I will try to explain and hopefully someone has the answer.
I have the 2 user tables, users and user_permissions.
In the user table there are additional columns named district_id, district, gemeente_id and gemeente. I also have 2 extra tables in the database called districten and gemeenten.
The districten table has 2 colums. id and district which holds the unique ID and the name. The gemeente table has at least these 3 columns id, district_id and gemeente.
Here is what I would like to happen:
When the user logs in the query will give a result in an <ul> in the navbar where it will show all values (column gemeente) from the gemeenten table where the user has been assigned to.
Example:
User ZZZ is assigned to district A.
This district holds 4 gemeenten : City 1, City 2, City 3 and City 4
When the user logs in, he should
only see the cities from the District A.
I don't know how to get this working in Slim2 Framework and integrated in the PHP Authentication code. So any help is much appreciated.
First you have to normalize your table and get rid of redundant information since it's hard to maintain it in relational database(I assume here you're using relational database like MySQL).
So basically each user is assigned to gemeente, each gemeente assigned to district and district in his turn has cities(gemeenten). In user table you only need the gemeente_id. The schema of districten and gemeente seems fine.
There are two way how to retrieve needed data: by running 2 queries(1 for fetch user's district; 2nd for fetch district's cities) and run everything in one query. Which way to choose is up to you.
1st approach:
SELECT d.id FROM district AS d LEFT JOIN gemeente AS g ON g.district_id=d.id LEFT JOIN user AS u ON u.gemeente_id=g.id WHERE u.id=<user_id>
SELECT g.id, g.gemeenten from gemeente as g where g.district_id = <res_of_prev_query>
2nd approach:
SELECT
g.id, g.gemeenten
FROM gemeente AS g
LEFT JOIN
districten AS d
ON g.district_id=d.id
INNER JOIN (
SELECT DISTINCT district_id, u.id AS user_id
FROM gemeente as gg
INNER JOIN user AS u
ON u.gemeente_id=gg.id) AS ud
ON ud.district_id=g.district_id
WHERE ud.user_id=<user_id>
You need transform this query to your ORM/ActiveRecord, run it and display the ul list
UPD: I've updated my answer. Thanks #DarkBee for pointing me to my mistake

SQL Count from Two Tables with Inner Join from Third Table

My database has two similar tables with different names. One of the columns contained in both tables is called "zips", which contains a zip code.
I have a different table (US zip code table) where each entry contains a county name, county ID, state, state ID, and zip code.
I need a query that will tell me how many entries in the first two tables match a given county ID, and will group the results by county.
That is, lets say table A has 4 entries for zip code '30017', and table B has 1 entry for '30017'. In the US zip code table, '30017' corresponds to the county name "Gwinnett" and the county ID '839'. When I run the query the desired result is:
Gwinnett 5
Here is the latest query I've tried. I have no idea what numbers it's returning. It's definitely not what I'm expecting, as I've tried the individual component queries to test the results.
SELECT b.County, COUNT(*) as Calls FROM (aLeads a, pLeads p)
INNER JOIN zipCodes b ON a.zip = b.ZipCode
WHERE b.countyID IN (2897, 2146, 839)
AND a.callDate BETWEEN '2013-10-01' AND '2013-11-30'
GROUP BY b.County
Any ideas?
Try starting with the zipcode table, and joining it with aLeads and pLeads:
SELECT b.County, COUNT(*) as Calls
FROM zipCodes b
INNER JOIN aLeads a ON a.zip = b.ZipCode
INNER JOIN pLeads p ON p.zip = b.ZipCode
WHERE b.countyID IN (2897, 2146, 839)
GROUP BY b.County

How do I generate several reports from one MySQL query?

I need to report the number of records that match each of several criteria. For example, how many customers live in each state. I know I can accomplish this through a series of MySQL SELECT statements, but that seems cumbersome and produces a ton of (unnecessary?) MySQL calls.
Can you tell me a better method to use? Can I query the database with one SELECT statement and then use PHP to filter the results to variables?
I'd suggest creating a view for this task just to hide the complexity of the query. Also, in the event that your table schema changes, it is likely that you are still going to want to retrieve this same information from the database. You'd be able to change the view in one place, instead of having to change the queries in, possibly, multiple places to satisfy your schema changes.
I'll just show you the queries, though, since you'd need to know how to do that to create a view anyways.
Sticking with your example of customers living in each state, let's pretend you also want statistics on how many customers share the same last name.
I've setup a mock structure of what your database might be like at this SqlFiddle.
Customers with Same LastName
The following query might be used to get the number of customers with the same last name:
SELECT
LastName AS "Value",
COUNT(*) AS "Count"
FROM Customers
GROUP BY
LastName;
Customers in Same State
Similarly, the customers in the same state might be retrieved with a query as follows:
SELECT
S.Name AS "Value",
COUNT(*) AS "Count"
FROM Customers AS C
INNER JOIN CustomerAddresses AS CA ON C.Id = CA.CustomerId
INNER JOIN Addresses AS A ON CA.AddressId = A.Id
INNER JOIN States AS S ON A.State = S.Id
GROUP BY
A.State;
Getting Your Desired Format
The format that you want is an aggregation of these two queries. You want both returned as a single result set. So, let's workout a schema for the returned table:
ResultType - This will hold a value that corresponds to the type of result. i.e. "State"
Value - This will hold the value of the aggregated column. i.e. "Florida"
Count - This will hold the total number of records that match the aggregated column.
So, now that we have a format, let's create a query that uses our two queries from above, and puts them into this format.
First, I add a new field to each of the above queries: ResultType
For example:
"LastName" AS "ResultType"
Now, I combine my queries into a single query using the UNION ALL statement:
SELECT * FROM (
/* LastName query */
SELECT
"LastName" AS "ResultType",
LastName AS "Value",
COUNT(*) AS "Count"
FROM Customers
GROUP BY
LastName
UNION ALL
/* States query */
SELECT
"State" AS "ResultType",
S.Name AS "Value",
COUNT(*) AS "Count"
FROM Customers AS C
INNER JOIN CustomerAddresses AS CA ON C.Id = CA.CustomerId
INNER JOIN Addresses AS A ON CA.AddressId = A.Id
INNER JOIN States AS S ON A.State = S.Id
GROUP BY
A.State
) AS A
In my SqlFiddle above, this produces an output like:
RESULTTYPE VALUE COUNT
=================================
LastName Jetson 1
LastName Johnson 2
LastName Milton 1
State Florida 2
State Georgia 1
State Utah 1
As you can see, this could get quite complex, so you might consider looking into placing this into a view. Then, you'd be able to query your view, as if it was the table above (ResultType, Value, and Count). That would also allow you to filter on it.
create select query make number of aliens of table and make your related columns aliens which is you want to use.
lest see sample example
SELECT a.id AS id
FROM Table1 AS a
WHERE ...
UNION ALL
SELECT b.name AS name
FROM Table2 AS b
WHERE ...
ORDER BY (a or b) ...

Need help in mysql query

I have three tables, one with the information about the client (name, username), another table with the service performed to his car (points obtained from the service), service made) and one with the company, representing where the client works (name, location).
I'm trying to make a query to get together the company where the client works, the client himself and the sum of all the points obtained. I already tried several approaches, but all failed. I want to display the client information even if it doesn't have any points.
This is what I already tried
SELECT *FROM client c
INNER JOIN company b ON c.company_idcompany = b.idcompany
INNER JOIN (select sum(pointos) as pointos From services) d
SELECT *FROM client c
INNER JOIN company b ON c.company_idcompany = b.idcompany
INNER JOIN service d ON c.idclient = d.client_idclient
You need to LEFT JOIN on your aggregated query. If you INNER JOIN, it will only return rows that have an entry in services. Clients with no services won't be returned. Try this
SELECT *FROM client c
INNER JOIN company b ON c.company_idcompany = b.idcompany
LEFT JOIN (select client_idclient,sum(pointos) as pointos From services group by client_idclient) d on c.idclient=d.client_idclient
If you need a zero rather than NULLs you can use IFNULL to convert the sum of the points.
Please, provide some more table structure data (as create script for example).
I think the problem is that you have to use LEFT JOIN in the joining and you are not providing any "connection information" in the first query's second join statement.

Mysql Query Relations M-M Table

I'm having a small problem making a query in MySQL.
I have the following tables:
member;
group;
member_has_group (this one has the columns id_group referes to the group id and id_member referes to member id)
I'm trying to make a query that gives me the members from a selected group. Can you help me?
I'm not familiar with join tables, but for the search i made i think thats probably one of the solutions.
Thanks in advance.
Elkas
If you know the group id
select member.* from member m
inner join member_has_group mg on m.id = mg.id_member
where mg.id_group = [x]
If you only know the group name
select member.* from member m
inner join member_has_group mg on m.id = mg.id_member
inner join group g on g.id = mg.id_group
where g.name = 'group name'
This is trival in SQL :
SELECT m.id_member, m.name
FROM member AS m
INNER JOIN member_has_group AS h ON (m.id_member=h.id_member)
WHERE (h.id_group=#my_id_group)
#my_id_group is the group id you have to give.
Yep, you need a join here.
SELECT *
FROM `member`
JOIN `group` ON member.id = group.id
JOIN `member_has_group` ON group.id = member_has_group.id
Depending on the information in your tables, you may not need the third table at all.You only need a connector table with you have a "many to many" relationship between then.
(Ignore the rest if you already know
about database normalization)
For example, if you had two tables, Authors and Books. Authors would contain fields such as Name, Publisher, Birthday, whatever is a property of the "author". Books would contain relevant "book" information. This is a "one-to-many" relationship. An author may be linked (via a field such as author_id) to several books, but a book can only have one author. You would not need a third table here.
Building on that, say you had a third table for "Character Names". This would be a list of main character names used in any of the books in the "Books" table. One of the characters happens to be named John Steele. John has a whole series of books written about him. In the Books table, several of the books may list John Steele as a character. While in the characters table, John Steele could be listed in several books. This is "many-to-many". You need a third table here. It would only have two fields. A book_id and character_id, one entry for each book that John Steele appears in.
MySql Manual on DB Normalization

Categories