I have this type of model(schema)
1 product hasOffer (many) Offers
1 offer hseRule (many) shipment rules
like
Product(1)--->Offer(N)----->Rules(M)
How can I query
one product with all offers and all shipping rules.
In simple words.
How can I query one-many related records ?
This can be achieved using a simple SPARQL query with multiple triples in the WHERE clause. This works because the graph model over which SPARQL queries naturally joins data together.
eg.
SELECT ?product ?offer ?rules
WHERE { {?product ns:hasOffer ?offer} {?offer ns:hasRules ?rules} }
Source: Running the same example in Protege with this query.
EDIT:
Question: is there any way to construct as product{ offers:{ rules:{} }, productAttributes } ?
Answer: Yes there is, you can add ?attribute to the SELECT clause the triple ?product ns:productAttribute ?attribute to the WHERE clause (or multiple such clauses if you have attributes across multiple data properties). However I would strongly recommend you refrain from doing so. The query is going to return a potentially large set of data similar to an SQL result set. Thus you are going to see multiple rows with the same product and having a product attribute there will make your life unnecessarily difficult, since that attribute will appear in all rows with that product. Instead run a separate query where you only get the products and their attributes.
Related
I think I got a knot in my line of thought, surely you can untie it.
Basically I have two working queries which are based on the same table and result in an identical structure (same as source table). They are simply two different kinds of row filters. Now I would like to "stack" these filters, meaning that I want to retract all the entries which are in query a and query b.
Why do I want that?
Our club is structured in several local groups and I need to hand different kinds of lists (e.g. members with email-entry) to these groups. In this example I would have a query "groupA" and a query "newsletter". Another could be "groupB" and "activemember", but also "groupB" and "newsletter". Unfortunately each query is based on a set of conditions, which imho would be stored best in a single query instead of copying the conditions several times to different queries (in case something changes).
Judging from the Venn diagrams 1, I suppose I need to use INNER JOIN but could not get it to work. Neither with the LibreOffice Base query assistant nor an SQL-Code. I tried this:
SELECT groupA.*
FROM groupA
INNER JOIN newsletter
ON groupA.memberID = newsletter.memberID
The error code says: Cannot be in ORDER BY clause in statement
I suppose that the problem comes from the fact, that both queries are based on the same table.
May be there is an even easier way of nesting queries?
I am hoping for something like
SELECT * FROM groupA
WHERE groupA.memberID = newsletter.memberID
Thank you and sorry if this already has a duplicate, I just could not find the right search terms.
We query a relational database using standardized SQL. The result of a query is a two dimensional table; rows and columns.
I really like the well structure of a rdms (i honestly never worked professionally with other db systems). But the query language or more exactly the result set sql produces is quite a limitation affecting performance in general.
Let's create a simple example: Customer - Order (1 - n)
I want to query all customers starting with letter "A" having an order this year and display each with all his/her orders.
I have two options to query this data.
Option 1
Load data with a single query with a join between both tables.
Downside: The result which is transferred to the client, contains duplicated customer data which represents an overhead.
Option 2
Query the customers and start a second query to load their orders.
Downsides: 2 queries which result in twice the network latency, the where in term of the second query can potentially be very big, which could lead to query length limitation violation, performance is not optimal because both queries peform a join/filtering to/of orders
There would be of course an option three where we start query with the orders table.
So generally there exists the problem that we have to estimate based on the specific situation what the better trade is. Single query with data overhead or multiple queries with worse execution time. Both strategies can be bad in complex situations where a lot of data in well normalized form has to be queries.
So ideally SQL would be able to specify the result of a query in form of an object structure. Imagine the result of the query would be structured as xml or json instead of a table. If you ever worked with an ORM like EntityFramework you maybe know the "Include" command. With support of an "include" like command in sql and returning the result not as join but structured like an object, world would be a better place. Another scenario would be an include like query but without duplicates. So basically two tables in one result. To visualize it results could look like:
{
{ customer 1 { order 1 order 2} }
{ customer 2 { order 3 order 4} }
} or
{
{ customer1, customer2 }
{ order1, order2, order3, order4 }
}
MS SQL Server has a feature "Multiple Result Sets" which i think comes quite close. But it is not part of Standard SQL. Also i am unsure about ORM Mappers really using such feature. And i assume it is still two queries executed (but one client to server request). Instead of something like "select customers include orders From customers join orders where customers starts with 'A' and orders..."
Do you generally face the same problem? How do you solve it if so? Do you know a database query language which can do that maybe even with existing ORM Mapper supporting that (probably not)? I have no real working experience with other database systems, but i don't think that all the new database systems address this problem? (but other problems of course) What is interesting is that in graph databases joins are basically free as far as i understand.
I think you can alter your application workflow to solve this issue.
New application workflow:
Query the Customer table which customer start with a letter 'A'. Send the result to client for display.
User select a customer from client and send back the customer id to server
Query the Order table by the customer id and send the result to client for display.
There is a possibility to return json on some SQL-Server. If you have a table A relate to table B and every entry on table point to maximum one entry at table A then you can reduce overload on traffic as you described. On example could be an address and their contacts.
SELECT * FROM Address
JOIN Contact ON Address.AddressId = Contact.AddressId
FOR JSON AUTO
The SQL return result would be smaller:
"AddressId": "3396B2F8",
"Contact": [{
"ContactId": "05E41746",
... some other information
}, {
"ContactId": "025417A5",
... some other information
}, {
"ContactId": "15E417D5",
... some other information
}
}
]
But actually, I don't know any ORM which process JSON for traffic reduction.
If you had some contacts for different addresses it could be counterproductive.
Don’t forget that JSON also has some overhand and it need to be serialized and deserialized
The optimum for traffic reduction would be if the SQL-Server split the joined result in Multiple Result Sets and the client respectively the Object-Relational-Mapper map them together. I’m would be interested if you find a solution for your problem.
Another train of thought would be to use a graph database.
When I specify multiple IDs as query parameters in my conceptual search, would the results have only those documents which refer conceptually to all of the searched IDs? Or will it have documents that refer conceptually to any one of the IDs?
Thanks
Vipin
The intended behavior of passing multiple ids to the /conceptual_search query is a logical AND. So the search is trying to find documents that have relationship to all the ids listed in the query.
The OR behavior cannot be performed through a single query, but can be emulated by performing separate queries to the individual ids, followed by a merge (with proper sorting) of the results on the client side.
I an trying to find a way to determine whether or not an SQL SELECT query A is prone to return a subset of the results returned by another query B. Furthermore, this needs to be acomplished from the queries alone, without having access to the respective result sets.
For example, the query SELECT * from employee WHERE salary >= 1000 will return a subset of the results of query SELECT * from employee. I need to find an automated way to perform this validation for any two queries A and B, without accessing the database that stores the data.
If it is unfeasable to achieve this without the aid of an RDBMS, we can assume that I have access to a local, but empty RDBMS, but with the data stored somewhere else. In addition, this check must be done in code, either using an algorithm or a library. The language I am using is Java, but other language will also do.
Many thanks in advance.
I don't know how deep you want to get into parsing queries, but basically you can say that there are two general ways of making a subset of a query (given that source table and projection(select) staying the same):
using where clause to add condition to row values
using having clause to add conditions to aggregated values
So you can say that if you have two objects that represent queries and say they look something close to this:
{
'select': { ... },
'from': {},
'where': {},
'orderby': {}
}
and they have select, from and orderby to be the same, but one have extra condition in the where clause , you have a subset.
One way you might be able to determine if a query is a subset of another is by examining their source tables. If you don't have access to the data itself, this can be tricky. This question references using Snowflake joins to generate database diagrams based on a query without having access to the data itself:
Generate table relationship diagram from existing schema (SQL Server)
If your query is 800 characters or less, the tool is free to use: https://snowflakejoins.com/index.html
I tested it out using the AdventureWorks database and these two queries:
SELECT * FROM HumanResources.Employee
SELECT * FROM HumanResources.Employee WHERE EmployeeID < 200
When I plugged both of them into the Snowflake Joins text editor, this is what was generated:
SnowflakeJoins DB Diagram example
Hope that helps.
I have a database which has multiple nested associates. Basically, the structure is as follows:
Order -> OrderItem -> OrderItemPlaylist -> OrderPlaylistItem -> Track -> Artist
I need to generate a report based on all orders sold in a certain date, which needs to traverse into ALL the mentioned associations in order to generate the required information.
Trying to join all tables together would be an overkill, as it would result in an extremely large cartesian join with many redundant data, considering it would be joining 6 tables together. Code below:
q.Left.JoinQueryOver<OrderItem>(order => order.OrderItems)
.Left.JoinQueryOver<OrderItemPlaylist>(orderItem => orderItem.Playlist)
.Left.JoinQueryOver<OrderItemPlaylistItem>(orderItemPlaylist => orderItemPlaylist.PlaylistItems)
.Left.JoinQueryOver<Track>(orderItemPlaylistItem => orderItemPlaylistItem.Track)
.Left.JoinQueryOver<Artist>(track => track.Artist)
The above works, but with even a few orders, each with a few order items, and a playlist each consisting of multiple tracks, the results would explode to thousand records, growing exponentially with each extra order.
Any idea what would be the best and most efficient approach? I've currently tried enabling batch-loading, which greatly scales down the number of database queries but still does not seem to me like a good approach, but more like an 'easy-workaround'.
There is no need for all the data to be loaded in just one SQL query, given the huge amount of data. One SQL query for each association would be perfect I guess. Ideally it would be something where first you get all orders, then you get all the order items for the order and load them in the associated collections, then the playlists for each order item, so on and so forth.
Also, this doesn't have to be specifically in QueryOver, as I can access the .RootCriteria and use the Criteria API.
Any help would be greatly appreciated !
I believe this is what you are looking for
http://ayende.com/blog/4367/eagerly-loading-entity-associations-efficiently-with-nhibernate
If you prefer one SQL query, what SQL syntax would you expect this to produce? I guess you can't avoid a long sequence of JOINs if you're going for one SQL query.
I guess what I would do is get the entities level by level, using several queries.
You should probably start off by defining the query as best you can in SQL, and looking at the execution plans to find the very best method (and whether your indexes are sufficiant).
At that point you know what you're shooting for, and then it's reasonably easy to try and code the query in HQL or QueryOver or even LINQ and check the results using the SQL writer in NHibernate, or the excellent NHProfiler http://www.nhprof.com.
You are probably right about ending up with several queries. Speed them up by batching as many as you can (that do not depend on each other) into single trips by using the "Future" command in Criteria or QueryOver. You can read more about that here: http://ayende.com/blog/3979/nhibernate-futures