writing SQL queries to get neighbour rows - sql

I have come across some problems writing queries for getting neighbour rows and have no idea what to do about it.
This is the scenario (it is not purely implemented using SQL at the moment, but rather a mix of SQL and Java implementation) :
There is an entity A which has 1000 entity B, each entity B has 1000 entity C, each entity C has 1000 entity D. We need to use the information stored in D. At first we have a query to get all entity Ds inside entity A. Then we implement some logic so that we can navigate from a particular D to the next D or previous D, but this logic is not written as SQL queries.
Question 1
If I want to implement the navigation logic as SQL queries, how can I go to the next D in my select query? Suppose the original query is as simple as
select * from D
inner join C where C.ID = D.FK
inner join B where B.ID = C.FK
I am looking for a universal solution for both Oracle and SQL Server.
Question 2
How do I know what position is the current row (within the result of the above query). For example, if I want to implement some logic like "This is No. X of Y".
For those who are confused about what neighbor rows is, I mean the previous or next row of each row we get from the above query. The result query might be quite different with the one above, but you get the idea, I can specify the position of a particular D in the whole entity A using JAVA but I don't know how to do that using SQL.

If you are using Oracle, look into the LEAD and LAG keywords, they allow you to select with information from the rows before or after.

Related

informatica multi correlated subquery implementation

I am facing a task that due to my lack of experience with Informatica Components, in particular SQL Transformation, I did not implemented yet.
So what would be the best approch in PowerCenter to implement this kind of subquery:
SELECT
A.ID,
NVL2(A.SACHKONTO, B.KLAMMER, A.ID) AS KLAMMER
FROM
Table1 A,
(SELECT
A.ID AS KLAMMER,
B.ID
FROM
(SELECT
ID,
ID AS VON_ID,
LEAD(ID,1) OVER (ORDER BY ID) - 1 AS BIS_ID
FROM
Table1
WHERE
SACHKONTO IS NULL) A,
Table1 B
WHERE
B.ID BETWEEN A.VON_ID AND A.BIS_ID
) B
WHERE
A.ID = B.ID
So I tried different approch with small successed.
The first was to "decompose" the SQL in it's small part(I will refer if necessary or edit the question).
I also tried to put the all query (after have adapted it to Informatica SQL "language", but without success.
This is the most close solution that i got to replicate such query, without considerting performance important(I did use an SQL Override in the SQ), but as from the table result, the join is been not propely processed, then I believe I need to add another pipeline to let execute the join in the proper order:
My mapping solution:
You could put the subquery into a lookup transformation and then match the records coming through from the outer query (which i assume will be what you're putting into your zource qualifier per the A.ID = B.ID from the original query and then filter the nulls later)
Or you could similarly use 2 source qualifiers (one for the parent query and another for the subquery) followed by a joiner transformation with normal join type. This way will filter your source data sooner than my first option so performance wise should be better.
Final option is to use a source qualifier with sql override same as your current query... filters record out right at the database so a plus there (so long as the query itself is optimal) but sql overrides are not validated in the wider mapping context and can spring unexpected surprises so should be used with a lot of caution.

Is exist a simple way to select all data from specific table

I have two tables: A, B. I need to select all data from B.
I could do this like
SELECT id, b1, b2, ... b20 FROM A,B WHERE A.id = B.id;
it's not cool solution. I will need to update this statement if I modify B's database. Is exist something like ?
SELECT *(B)
It selected all data from B and didn't selected any data from A.
My databases
A
id
a1
a2
...
a20
B
id
b1
b2
...
b20
So if you want create database seriously you shouldn't see on complexity of way but on efficiency and speed. So my advice to you is use JOIN that is the best solution for selecting data from two and more tables, because this way is fast as possible, at least for my more cleaner like for example inserted select.
You wrote: I need to select all data from B this means SELECT * FROM B not that you wrote.
My advice to your is using this:
SELECT * FROM A <INNER / LEFT / RIGHT / NATURAL> JOIN B ON A.id = B.id;
or to select specific columns
SELECT A.column1, A.column2, ... FROM A <INNER / LEFT / RIGHT / NATURAL> JOIN B ON A.id = B.id;
Note:
NATURAL JOIN will work in above example since the primary key
and the foreign key in the two tables have the same name. So you must be very
careful in using NATURAL JOIN queries in the absence of properly
matched columns.
So you really should think about how you will create database and how you will working with database, how you will pulling data for View from database, how you will insert new potential data to database etc.
Regards man!
Use following query:
SELECT * FROM B;
or
SELECT * FROM B INNER JOIN A ON A.id = B.id;
if you want to join tables A and B.
I suspect that the others have sufficiently answered your question about selecting all fields from table B. That's great, as you really should understand the SQL basics. If they haven't, I'd also advise that you check out SQLite.org site for a clarification on SQL syntax understood by SQLite.
But, assuming you've answered your question, I just want to voice two words of caution about using the asterisk syntax.
First, what if, at some later date, you add a column to B that is a big hairy blob (e.g. a multimegabyte image). If you use the * (or B.*) syntax to retrieve all of the columns from B, you may be retrieving a ton of information you might not need for your particular function. Don't retrieve data from SQLite if you don't need it.
Second, is your Objective C retrieving the data from your select statement on the basis of the column names of the result, or based upon the index number of the column in question. If you're doing the latter, then using the * syntax can be dangerous, because you can break your code if the physical order of columns in your table ever changes.
Using named columns can solve the problem of memory/performance issues in terms of retrieving too much data, as well as isolating the Objective C from the physical implementation of the table in SQLite. Generally, I would not advise developers to use the * syntax when retrieving data from a SQL database. Perhaps this isn't an issue for a trivial project, but as projects become more complicated, you may want to think carefully about the implications of the * syntax.
I don't know if the following query would work in sqlite, I know it works in Oracle, but you can give it a try...
SELECT B.* FROM A,B WHERE A.id = B.id;

NHibernate HQL subselect left join?

I have the following issue and I would really appreciate your help:
I have all my filtering done through the HQL and one of the filters is a left outer join which must be a sub-select. So my thinking here is that I can create a dummy business object which I would like to populate (with an SP if possible) with data and use it in my left join.
Now how can I do that and still have all of the logic in 1 HQL query?
I guess the biggest issue for me is understanding how can I have this BO (not actually mapped to a table etc.) be used in a query where all the other BOs are mapped to tables etc.
I am trying to avoid doing any filtering in the actual C# code.
Thanks!
Example:
Entity A - mapped to table A
Entity B - mapped to table B
Entity C - mapped to table C
Entity D - not mapped to table - coming from SQL query or SP
HQL:
from A pbo
inner join B.EntityType etype
inner join C.EntityAddressList eadr
left join D.Level lvl
You cannot join to arbitrary SQL in HQL. So I don't think what you're trying to do is possible. You'll likely either have to map whatever D is, or write your query in SQL using Session.CreateSQLQuery(). You can still specify any entities that come back. See this article for reference. http://www.nhforge.org/doc/nh/en/index.html#d0e10274

Does the SQL spec provide for a better way to do a exclusive ORing of two sets?

I have a result set A which is 10 rows 1-10 {1,2,3,4,5,6,7,8,9,10}, and B which is 10 rows consisting of evens 1-20 {2,4,6,8,10,12,14,16,18,20}. I want to find of the elements that are in one set but not both. There are no other columns in the rows.
I know a UNION will be A + B. I can find the ones in both A and B with A INTERSECT B. I can find all of the rows in A that are not in B with A EXCEPT B.
This brings me to the question how do I find all rows that are in A or B, but not both, is there a transitive equiv of ( A EXCEPT B ) UNION ( B EXCEPT A) in the sql spec? I'm wanting a set of {1,3,5,7,9,12,14,16,18,20}. I believe this can also be written A UNION B EXCEPT ( A INTERSECT B )
Is there a mathy reason in set theory why this can't be done in one operation (that can be explained to someone who doesn't understand set theory)? Or, is it just not implemented because it is so simple to build yourself? Or, do I just not know of a better way to do it?
I'm thinking this must be in the SQL spec somewhere: I know the thing is humongous.
There's another way to do what you want, using a FULL OUTER JOIN with a WHERE clause to remove the rows that appear in both tables. This is probably more efficient than the constructs you suggested, but you should of course measure the performance of both to be sure. Here's a query you might be able to use:
SELECT COALESCE(A.id, B.id) AS id
FROM A
FULL OUTER JOIN B
ON A.id = B.id
WHERE A.id IS NULL OR B.id IS NULL
The "exclusive-or" type operation is also called symmetric set difference in set theory. Using this phrase in search, I found a page describing a number of techniques to implement the Symmetric Difference in SQL. It describes a couple of queries and how to optimise them. Although the details appear to be specific to Oracle, the general techniques are probably applicable to any DBMS.

NHibernate : Count childrens' children

I have an entity type A. Which has many B's. The B entity has many C's.
I need to count how many C's does an A entity have. How can this be done using NHibernate Criteria API?
Using LINQ to NHibernate I was unable to get results since it throws an exception (see this question)
This query becomes simpler if you use C as starting point of the query, rather than A. This is possible since you use bidirectional mappings, according to the mapping you show in your other question.
The way I would do this is to find all Cs which have a B which has a given A, and then count the found Cs.
To Add a constraint on the B of a C, you can add an alias and then add restrictions to that alias. To perform a count query rather than returning the found Cs you can use the SetProjection method and specify a Count projection. Since the count projection returns a single integer value, use UniqueResult to get the count.
using (ISession session = SessionFactorySingleton.OpenSession())
{
int numberOfCsForA1 = session.CreateCriteria<C>()
.SetProjection(Projections.Count("Id"))
.CreateAlias("B", "b")
.Add(Restrictions.Eq("b.A.Id", a1.Id))
.UniqueResult<int>();
// ...
}
The SQL generated by this query looks like this:
SELECT count(this_.Id) as y0_
FROM [C] this_
inner join [B] b1_
on this_.IdB=b1_.Id
WHERE b1_.IdA = #p0;#p0 = 12
As you can see, it is a two-way join, since NHibernate is smart enough to realize that it does not need to join with the A table to get the id of a Bs A. Instead it simply looks at the IdA value of the B.