Can any one explain me about self-join in oracle with simple example? - self-join

Can any one explain me about self-join in oracle with simple example.i have searched in many sites but i couldn't understand..

Suppose you have employee table
ID NAME MANAGER_ID
1 Andy 10
2 Bill 10
3 Chaz 11
10 Joy 12
11 Kath 12
12 Lois (null)
And you want to select someone and their manager.
SELECT FROM EMPLOYEE PERSON, EMPLOYEE MANAGER WHERE EMPLOYEE.MANAGER_ID = MANAGER.ID
So the key idea is that we are using the EMPLOYEE table in two ways, to find people, and to find managers.
This probably doesn't fully explain what you want to know, maybe you could now explain in more detail what you don't understand.

Related

SQLite JOIN trouble

I'm trying to learn the basics of SQL by setting up a simple database in SQLite.
I created two tables, "people" and "departments"
The people table has three columns: ID(primary key), Name and Age;
The departments table has two columns: ID(primary key) and DeptName;
A single person can work in more than one department, so I created a third table "P2D" with two columns, "PpID" and "DpID" constrained to the ID columns of the other two tables. Maybe there's a better way to do this, but that's what I figured out (is it?)
Now, I need to make a query to display people name, age and departments. I made this:
SELECT Name 'Worker Name',
Age,
group_concat (DeptName,', ') Departments FROM People
LEFT JOIN P2D ON People.ID=P2D.PpID
LEFT JOIN Departments ON P2D.DpID=Departments.ID
GROUP BY Name;
And here's the output:
Worker Name Age Departments
1 George Washington 30
2 Peter 24 Storage, Accountancy
3 Roger 21 Sales, Storage
4 Wilco 71 Burps and Farts
As you can see, George Washington is not in any department, because I didn't put his ID into the P2D table.
Is there a way to display something, like i.e. "Idle" instead of the blank NULL cell?
Thanks, and sorry for my stuttering English.
You could use COALESCE(), since GROUP_CONCAT() output is NULL for 0 results:
SELECT
Name 'Worker Name',
Age,
COALESCE(group_concat(DeptName, ', '), 'Idle') Departments
FROM People
COALESCE outputs the first non-null argument.
Personally, I rather do that bit in code, not in the db, because NULL is perfectly checkable in code/a template. You can print "Idle" instead of Departments, or show an icon, or remove a link, etc. If you always return text, your code doesn't know if it means department names, or actually no departments.
Your P2D solution is common and good. It's a link or pivot table.

Query to get 4 elements for each Unique Country for Room

Please refer to the table in the image attached. https://i.stack.imgur.com/JGHfK.png (From W3Schools)
What I am trying to achieve is to get at max 4 elements from each unique country
Pseudo code:
1) Find all distinct countries (Mexico, USA, Canada, etc)
2) get any 4 elements for each of those unique countries.
Expected Outcome:
4 random people for Mexico
4 random people for USA
1 random people for Canada (Total people from Canada in table = 1)
3 random people from India (Total people from India in table = 3)
The query for SQLite is
select * from(
select *, ROW_NUMBER() OVER (PARTITION BY Country ORDER BY Country DESC) AS rn
from Customers) sub
where sub.rn < 5
But my question is how can i convert this for Room Query in Android. Is it even possible?
I would just need the LiveData from the query of the room. I can then parse the result to handle the data.
I am not really the database guy so I am struggling with this.
Any help is appreciated.
Thank you
In short you will have to use an alternative query that doesn't use Window Functions.
Support for Window functions and therefore the use of OVER was introduced in SQLite 3.25.0.
The highest supported version of SQLite in the official Android list is SQLite 3.19. As such OVER is invalid syntax and you cannot use Window functions. android.database.sqlite

Find duplicate values in 2 different columns in one table using SQLite

EmpID EmpName LineManager eMail
=========================================================
11111 Alex Sanchez Robert Wham alex#abc.com
22222 Willis Max Nara Zee willis#abc.com
33333 Robert Wham Melissa Baker robert#abc.com
44444 Nara Zee Jane Stewart nara#abc.com
In the example above, Robert Wham and Nara Zee are both line managers and employees.
I need a SQLite query to find such a case and retrieve the following:
EmpID
Duplicate Name AS Emp_Line
eMail of Emp_Line
Thanks for all....
Do a self join from employee to line manager:
SELECT
t1.*
FROM yourTable t1
INNER JOIN yourTable t2
ON t1.EmpName = t2.LineManager
This would return each record for an employee who happens to also have an entry as a line manager. If there could be more than one record for an employee, then you could use SELECT DISTINCT instead. Note that your table is not very robust, in the sense that more than one employee or manager could have the same name. Ideally you would store a unique employee ID of some kind and we could join on that instead.

How to define some tables in SQLite

I am trying to make a database to manage expenses between people. I want a table where I can save how many euros has spend every person.
I have a table called people which only have two columns, _id and name.
Then I am trying to create a table with _id, total amount and save how many euros has spend everyone. I was thinking in made a column for each person with his _id and put how many euros has spend, but I don't know how to do it.
For example:
Or maybe I could use some columns to store the id and the amount, like this:
(it is the same example)
Thank you in advance!
You propose two separate SQL antipatterns there. One is having columns that are named by another table, and the other is having a blah_1, blah_2, … series of columns. In each case they indicate that you're thinking about this wrong; a database is not a spreadsheet.
You would be better off having a table that records the unique mapping between transaction ID, person ID and how much they spent (omitting the _id for clarity):
txID | personID | spend
-----+----------+-------
1 | 1 | 10
2 | 1 | 5
2 | 2 | 10
3 | 2 | 10
3 | 3 | 10
4 | 1 | 4
You'll want to specify that the combination of txID and personID is unique, but not that either column is unique in itself.
Now that's not to say that you've lost the amount that anyone's spent or other basic aggregate info like that. You can then derive the total amount spent in a transaction using a query like:
SELECT SUM(spend) AS "Total amount" FROM spendTable WHERE txID = 2
However, you can also do things like finding out how much someone has spent in total:
SELECT SUM(spend) FROM spendTable WHERE personID = 1
Such a query is entirely sensible, and would be much more difficult with the second table design you proposed. (The first design would be better, except then you can't actually explicitly link with the PEOPLE table via a foreign key relation, which would make things much trickier as soon as you start doing anything more complex.)

Concatenating record values in database (MS Access) or in server side code (ASP.NET)

sorry to bother you people again. I've searched all over the internet but I can't find the solution to my problem. I have two tables in Access and the output is like this:
MATH 5
ENGLISH 3
ENGLISH 2
PHYSICS 5
MATH 1
MATH 3
I want it to be:
MATH 5, 1, 3
ENGLISH 3, 2
PHYSICS 5
How can I accomplish this? It tried playing with SQL commands in Access database but nothing works. I also looked for solution using the GridView in ASP.NET but no luck either. Is there a way to acomplish this or should I take a different approach?
Best I can do is GROUP BY so the output looks like this:
MATH 5
MATH 3
MATH 1
PHYSICS 3
PHYSICS 1
...
I believe you are looking for something like this -
Join collection of objects into comma-separated string
I would be inclined to pull the data back as you have done in you GROUP BY in the question, and then concatenate the number values for each subject in you asp.net code.
Or you could write a VBA function to use in Access to do it. One has already been written by Allen Browne here. You just need to add the code to a module within Access and then you can use that function within SQL queries within Access.
Given this table structure
subjects table
id | SubjectName | Grade
---------------------------------
1 MATH 5
2 ENGLISH 3
3 ENGLISH 2
4 PHYSICS 5
5 MATH 1
6 MATH 3
The following SQL with the VBA function
SELECT
subjects.SubjectName + ' ' +
ConcatRelated("Grade","subjects","SubjectName='" & SubjectName & "'") AS result
FROM
subjects
GROUP BY
subjects.SubjectName
yields the following result
result
------------
ENGLISH 3, 2
MATH 5, 1, 3
PHYSICS 5
if you want to get the order that you have specified in your question, you will need another field/expression on which to do the ordering
There is an easy solution. Use the last() aggregate function in your query.
Sample:
SELECT RecNo, Last(fConcat([RecNo],[Field5])) AS Field5 FROM myTable GROUP BY RecNo;
The function Last() calls the function Concat for each record that will be grouped. Be aware to use global variables that are defined outside the function Concat.
The following is just a simple code as a proof of concept:
Option Compare Database
Dim glbWert1 As Variant, glbWert2 As Variant
Public Function fConcat(strWert1, strWert2) As Variant
If strWert1 <> glbWert1 Then
glbWert1 = strWert1
glbWert2 = strWert2
Else
glbWert2 = glbWert2 + "; " + strWert2
End If
fConcat= glbWert2
End Function
The solution works very fast
If I had MS Access and ASP.Net to solve this task, I'd take the route of nested repeaters.
So I'd make two calls to the database, first call to get the distinct categories (in your case -- IDSUBJECTS), the second call is to get all the GRADE fields for all the IDSUBJECTS. If you are doing it by the Username, then I would add Username into each of those calls.
Then I'd tie up the one repeater to the distinct IDSUBJECTS, put a Literal control and a repeater into the itemtemplate. Then I'd get the text from the literal control and a reference to the inner repeater in the Repeater_ItemDataBound event and filter the second table based on the IDSUBJECT in the outer repeater. In the inner repeater, iterate over the filtered data and display in the way you want.
Not the easiest solution, but it can work.
If you have a SQL Server (you can download Microsoft SQL Server Express for free), you may want to look into the PIVOT function.
A very interesting way to handle this if Microsoft SQL Server is an option is to use a Common Table Expression query. Using a CTE would allow you to concatenate your grade column into a single cell by class. Simple-Talk has a very nice walkthrough that explains different approaches to SQL contacenation and gives examples of using CTEs (look for the WITH statements).
If you don't have Microsoft SQL Server, download Microsoft SQL Server 2008 Express .

Resources