I have the following hql query which I'd like to switch over to the criteria API
select a.Id as Id, a.Name as Name, a.ActiveStatus as ActiveStatus,
dbo.GetActivityStartDate(a.Id) as StartDate,
dbo.GetActivityEndDate(a.Id) as EndDate,
coalesce(ac.Id,0) As CategoryId,
coalesce(ac.Name,'') As CategoryName
from Activity as a
left outer join a.Category as ac
Obviously the initial properties on the select line are trivial (Projections.Property); my question is..how do I map the remaining 4 properties?
I have a custom dialect that registers dbo.GetActivityStartDate and dbo.GetActivityEndDate as standard SQL functions - so that much is already taken care of.
So...it turned out that I needed to register the "ISNULL" function with my custom dialect; once I did that, it was a simple matter of using the Projections.SqlFunction to extract the data in the format I required.
Related
I recently started using GraphQL through a Hasura layer on top of a PostgreSQL DB. I am having troubles implementing a basic query.
Here are my entities :
article :
articleId
content
publishedDate
categoryId
category :
categoryId
name
createdDate
What I am trying to achieve, in English, is the following : get the articles that were published in the first 3 days following the creation of their related category.
In pseudo-SQL, I would do something similar to this :
SELECT Article.content, Category.name
FROM Article
INNER JOIN Category ON Article.categoryId = Category.categoryId
WHERE Article.publishedDate < Category.createdDate + 3 days
Now as a GraphQL query, I tried something similar to this :
query MyQuery {
articles(where: {publishedDate: {_lt: category.createdDate + 3 days}}) {
content
category {
name
}
}
}
Unfortunately, it does not recognise the “category.createdDate” in the where clause. I tried multiple variations, including aliases, with no success.
What am I missing ?
To my understanding of the Hasura docs, there is no way to reference a field within a query like you can do in SQL. But that does not mean, you can't do, what you are trying to do. There are three ways of achieving the result that you want:
1. Create a filtered view
CREATE VIEW earliest_articles AS
SELECT Article.*
FROM Article
INNER JOIN Category ON Article.categoryId = Category.categoryId
WHERE Article.publishedDate < Category.createdDate + 3 days
This view should now become available as a query. Docs for views are here.
2. Create a view with a new field
CREATE VIEW articles_with_creation_span AS
SELECT
Article.*,
(Article.publishedDate - Category.createdDate) AS since_category_creation
FROM Article
INNER JOIN Category ON Article.categoryId = Category.categoryId
Now you can again query this view and use a filter query on the extra field. This solution is useful if you want to vary the amount of time, that you want to query for. The downside is, that there are now two different article types, it might make sense to hide the regular articles query then.
3. Use a computed field
You can also define computed fields in Hasura. These fields are not only included in the output object type of the corresponding GraphQL type, but they can also be used for querying. Refer to the docs on how to create a computed field. Here you can again, calculate the difference and then use some kind of comparison operator (<) to check if this time is smaller than '3 days'.
I have this query:
SELECT SomeTableA.*
FROM SomeTableB
LEFT JOIN SomeTableA USING (XYZ)
GROUP BY SomeTableA.*
I know that I cannot do the GROUP BY part with wildcards. At the same time, I don't really like listing all the columns (can be up to 20) manually.
Could this be added as new feature? Or is there any way how to easily get the list of all 20 columns from SomeTableA for the GROUP BY part?
If you really have the exact query shown in your question - then try below instead - no grouping required
#standardSQL
SELECT DISTINCT *
FROM `project.dataset.tableA`
WHERE xyz IN (SELECT xyz FROM `project.dataset.tableB`)
As of Group By Using Wildcards in Big Query this sounds more like grouping by struct which is not supported so you can submit feature request if you want - https://issuetracker.google.com/issues/new?component=187149&template=0
Using Microsoft Access, I normally use condition (mostly where) to obtain the data I want to display.
So far, it went well. However now I have a complex filtering and I'm not sure of the best way to do it. I will explain how I do it with many queries, and I'd like to know if there is something simpler, since I feel like it's doing too much for what I accomplish.
I have Building and Energy tables. Between them, I have a link table since a Building has a list of possible energies.
My goal is to display ALL energy not already associated with the building.
I first have a simple query to display all the IDs of energy that are in the link table where building is the one of interest.
Once I do that, I have another query using this one, which display an energy if it is an energy absent from previous list.
This takes 2 queries and I feel like I could have a better way to do this. I'm fairly new to MS Access, so any suggestion is welcome.
Here is the first request to obtain the list of energies:
SELECT
Batiments.ID, Energies.ID, Energies.Type
FROM
Energies
INNER JOIN
(Batiments
INNER JOIN
Batiment_Energie ON Batiments.ID = Batiment_Energie.Batiment_ID) ON Energies.ID = Batiment_Energie.Energie_ID
WHERE
(((Batiments.ID) = " & cbxBatiments.Column(0) & "));"
You can query the non-associated energy types with
SELECT
ID, Type
FROM
Energies
WHERE
ID NOT IN (SELECT Energie_ID
FROM Batiment_Energie
WHERE Batiment_ID = 123)
where 123 is to be replaced by the Id comming from cbxBatiments.Column(0).
You can use not exists:
select e.*
from energie as e
where not exists (select 1
from Batiment_Energie as be
where be.energie_id = e.id and be.batiment_id = <your id>
);
I have a table defining constants in a single row. I want to construct a query on another table by using the value of these constants, something like:
SELECT DataTable.name FROM DataTable WHERE DataTable.key >
Config.keyConstant
but I have no idea how I can do this cleanly. In this case it could be done by using a CROSS JOIN
SELECT DataTable.name FROM (DataTable CROSS JOIN Config) WHERE DataTable.key >
Config.keyConstant
But this gets really messy as my queries get larger and the config is needed in different places.
Any suggestions? In SQL I'd think you'd do this with variables.
EDIT: Actually I want to be able to do something like
SELECT IF(Config.keyConstant*DataTable.key=1, DataTable.name, "John") FROM DataTable
This means that unfortunately I can't move all of the conditional logic into a WHERE EXISTS clause like suggested in an answer (although I wasn't aware of this, and it is cool).
I think you are in the right direction:
Something like below should work for both BigQuery Legacy and Standard SQL and having that Config has just one row makes CROSS JOIN not that bad looking.
SELECT DataTable.name
FROM DataTable
CROSS JOIN Config
WHERE DataTable.key1 > Config.key1Constant
AND DataTable.key2 = Config.key2Constant
AND DataTable.key3 < Config.key3Constant
In BigQuery Standard SQL you can change this to below, which somehow looks to me a little bit more portable:
SELECT
DataTable.name
FROM DataTable
WHERE EXISTS (
SELECT 1 FROM config
WHERE DataTable.key1 > key1Constant
AND DataTable.key2 = key2Constant
AND DataTable.key3 < key3Constant
)
Few notes:
cost wise - even though Config table is small - each time it will be contributing extra 10MB to the billing bytes
having extra column(s) in Config (like id ) will allow you to manage different versions of constants to be used by calling specific id value. Or condition based logic can be used to invoke needed constants
This is to answer updated question:
SELECT
CASE WHEN Config.keyConstant*DataTable.key=1
THEN DataTable.name ELSE "John"
END as name
FROM DataTable
CROSS JOIN Config
I have a lot of difficulties in trying to translate this SQL query to a DQL one (I am using Symfony2).
SELECT d.* FROM Document d JOIN DocumentType dt ON dt.id = d.document_type_id WHERE (d.dateFinal - INTERVAL dt.renewal SECOND) > NOW();"
Thanks a lot !
Instead of database fields, you need to use the fields of you Document and DocumentType classes.
The join is done by naming the association field of your document (something like d.documenttype)
For those MySQL date functions: At least as far as I know, you would need to write custom DQL functions. Behind that link there is an example of an INTERVAL function. This might be the point where you want to execute the native SQL query instead.
SELECT d
FROM MyProject\Model\Document d
JOIN d.documenttype
WHERE [...your own DQL functions here...]