postgresql query to get sum and columns from two tables using joins - c#

These are the tables that I have created: Tables
I want to get accounts.account,accounts.type,DATE(transactions.date),transactions.transactionid,transactions.amount,transactions.note from two tables between '10-11-2021' and '31-12-2021'.(whatever type may be)
I want to get Sum(account) from transactions table where type="income" and between '10-11-2021' and '31-12-2021'.
I want to get Sum(account) from transactions table where type="expense" and between '10-11-2021' and '31-12-2021'.
But I need all three queries in a single statement(that's what I am struggling)
My query:
SELECT accounts.account,accounts.type,DATE(transactions.date),transactions.transactionid,transactions.amount,transactions.note
FROM transactions
FULL JOIN accounts ON transactions.accountid=accounts.accountid
WHERE transactions.date BETWEEN '{0}' AND '{1}' ORDER BY transactions.date
UNION
select sum(amount)
FROM transactions
FULL JOIN accounts ON transactions.accountid=accounts.accountid
WHERE accounts.type='income'
I need to add other two queries also to fit above
can anyone help me?

Given the poor information about the source tables, the best I could is the following:
SELECT
a.account,
a.type,
DATE(t.date),
sum(case when t.type = 'income' then t.amount else 0 end) sum_of_income,
sum(case when t.type = 'expense' then t.amount else 0 end) sum_of_expense
FROM transactions t
left JOIN accounts a
ON t.accountid = a.accountid
group by
a.account,
a.type,
DATE(t.date)
tip: you shouldn't write your sql script in single-line code, almost never.
Also could be more informative to have table contents, or at least screenshots.

Related

.netcore EF linq - this is a BUG? Very strange behavior

I have two table in sql. Document and User. Document have relation to User and I want to get users that I sent document recently.
I need to sort by the date document was sent and get unique (distinct) user with relation to this document
This is my linq queries
var recentClients = documentCaseRepository.Entities
.Where(docCase => docCase.AssignedByAgentId == WC.UserContext.UserId)
.OrderByDescending(userWithDate => userWithDate.LastUpdateDate)
.Take(1000) // I need this because if I comment this line then EF generate completely different sql query.
.Select(doc => new { doc.AssignedToClient.Id, doc.AssignedToClient.FirstName, doc.AssignedToClient.LastName })
.Distinct()
.Take(configuration.MaxRecentClientsResults)
.ToList();
and generated sql query is:
SELECT DISTINCT TOP(5) [t].*
FROM (
SELECT TOP(1000) [docCase.AssignedToClient].[Id]
FROM [DocumentCase] AS [docCase]
INNER JOIN [User] AS [docCase.AssignedToClient]
ON ([docCase].[AssignedToClientId] = [docCase.AssignedToClient].[Id])
WHERE [docCase].[AssignedByAgentId] = 3
ORDER BY [docCase].[LastUpdateDate] DESC
)
AS [t]
Every thing is correct for now. But if I delete this line
.Take(1000) // I need this because...
EF generated completely different query such as:
SELECT DISTINCT TOP(5)
[docCase.AssignedToClient].[Id]
FROM [DocumentCase] AS [docCase]
INNER JOIN [User] AS [docCase.AssignedToClient]
ON ([docCase].[AssignedToClientId] = [docCase.AssignedToClient].[Id])
WHERE [docCase].[AssignedByAgentId] = 3
My question is: why EF not generated orderby clause and subquery with distinct?
This is a BUG EF or I'm doing something wrong? And what I must do to generate in linq this sql query ()
SELECT DISTINCT TOP 5 [t].*
FROM ( SELECT [docCase.AssignedToClient].[Id]
FROM [DocumentCase] AS [docCase]
INNER JOIN [User] AS [docCase.AssignedToClient]
ON [docCase].[AssignedToClientId] = [docCase.AssignedToClient].[Id]
WHERE [docCase].[AssignedByAgentId] = 1
ORDER BY [docCase].[LastUpdateDate] DESC
) AS [t]
OrderBy information not always retained across other operators such as Distinct. Entity Framework does not document (to my knowledge) how exactly OrderBy is propagated.
This kind of makes sense because some operators have undefined output order. The fact that ordering is retained in many situations is a convenience for the developer.
Move the OrderBy to the end of the query (or at least past the Distinct).
The reason for the difference in queries is that Distinct messes up result order. So when you first execute OrderBy and then Distinct, you can just es well not execute OrderBy, because this order is lost anyway. So EF can just optimize it away.
Calling Take in between causes the result set to be semantically different: You first order the items, take the first 1000 items of that order and then call Distinct on them.
What you can change in your query depends mainly on the result you want to achieve. Maybe you want to first make the result set distinct then order by date and finally take the amount of items. Other options are also thinkable based on your requirements.

Linq to Entities Union generating inner join to unioned table

I'm running in to an issue that's baffling me. When I try to union two tables together, the query to the second table is generating an inner join back to the the first table. The whole point of using the union is to return a result if the record exists in either table, but this inner join is causing it to fail if a record is in the second table, but not the first.
I did some testing on a much smaller scale to see if I'm going crazy, and that doesn't seem to be the case.
I have two tables, OrderDetails and OrderDetailHistories. Back story: After a certain period of time records are removed from the details table and put into the histories table. The fields and everything are exactly the same. In fact, this is the entity for OrderDetailHistories:
public partial class OrderDetailsHistory : OrderDetail { }
So, to start out, I wrote a little test query that's a pretty good representation of what I'm seeing.
var test = this.context.OrderDetails
.Select(x => x.Descr)
.Union(this.context.OrderDetailsHistories
.Select(x => x.Descr))
.Where(x => x == "wat")
.ToList();
Which generates this query:
SELECT
[Distinct1].[C1] AS [C1]
FROM ( SELECT DISTINCT
[UnionAll1].[Descr] AS [C1]
FROM (SELECT
[Extent1].[Descr] AS [Descr]
FROM [dbo].[OrderDetails] AS [Extent1]
WHERE N'wat' = [Extent1].[Descr]
UNION ALL
SELECT
[Extent3].[Descr] AS [Descr]
FROM [dbo].[OrderDetails_History] AS [Extent2]
INNER JOIN [dbo].[OrderDetails] AS [Extent3] ON ([Extent2].[Order_No] = [Extent3].[Order_No])
WHERE N'wat' = [Extent3].[Descr]) AS [UnionAll1]
) AS [Distinct1]
Huh? Why does that second select statement even reference the details table? What happens when I use a concat? Same thing. Intersect? Same inner join. Okay, maybe instead of unioning first, then applying my condition, I can apply the conditions to each query, then just union the results.
How about this?
var query1 = this.context.OrderDetails.Where(x => x.Descr == "wat").Select(x => x.Descr);
var query2 = this.context.OrderDetailsHistories.Where(x => x.Descr == "wat").Select(x => x.Descr);
var result = query1.Concat(query2).ToList();
Generates almost the exact same query! Does anyone know what's going on here? Are my expectations just off?
If I throw a .ToList() at the end of the query1 and query2 statements above it works exactly like I'd expect, but then I lose my ability to do paging in sql and end up pulling down far too many records, when we're only displaying 10 per page.
Any help would be appreciated.
I don't know what EF approach you are using, I suppose Code first. But anyways, you are using it wrong or you don't know how it works. When you inherit your OrderDetailsHistory class from OrderDetail then it says, that OrderDetailsHistory is always an OrderDetail.
So if you want to select all orders you can just query OrderDetail and there will be also all OrderDetailsHistory entities:
this.context.OrderDetails
.Select(x => x.Descr)
.Where(x => x == "wat")
.ToList();
It is also important to know how data are stored in your DB. You are using table per class aproach - read some articles about it (e.g. http://weblogs.asp.net/manavi/inheritance-mapping-strategies-with-entity-framework-code-first-ctp5-part-2-table-per-type-tpt ) to understand how it works, then you will also understand why all your queries look "so strange"...

How do you sum a column of a database to display total ratings in ASP.NET?

I'm trying to make a ratings system. I'm using visual studio. The database has 2 tables, one table for all the music tracks, and another table containing the ratings, and is hooked up with an FK.
Here's my tables and columns
http://i.gyazo.com/fc5d042749c8c04fb2b9aa2b64831b0a.png
This is my current attempt and it's giving me an error
SELECT DISTINCT Track.TrackId, SUM(Ratings.rating) AS average, Track.Name, Ratings.trackid
FROM Track
INNER JOIN Ratings
ON Track.TrackId = Ratings.trackid
Msg 8120, Level 16, State 1, Line 1
Column 'Track.TrackId' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Every time you are using either a sum, avr, min or max, etc. functions you have to use Group by that is the law..
What you need to do first is SUM the ratings by track and then joining those later with your track table, something like this:
SELECT T.TrackId, SUM(R.rating) AS average, T.Name
FROM Track T
INNER JOIN
(SELECT TrackId, SUM(Ratings.rating) AS average
FROM Ratings Group By TrackId ) R
ON T.TrackId = r.TrackId
If you want to use aggregation functions, then you generally want a group by. Without the group by, the query will return only one row.
SELECT t.TrackId, SUM(r.rating) AS average, t.Name
FROM Track t INNER JOIN
Ratings r
ON t.TrackId = r.trackid
GROUP BY t.TrackId, t.name;
In addition, I made the following changes:
Removed distinct from the select. This is almost never needed for an aggregation query.
Added table aliases that are abbreviations of the table names, to make the query more readable.
Removed Ratings.TrackId from the select statement. It is redundant, because it is the same as Track.TrackId.
Added a group by statement.
Don't use distinct. It doesn't do the same thing as Group By.
In SQL-think, what you're trying to do is group all the rows by Trackid, and average the rating in each group which you do like this:
SELECT Track.TrackId, AVG(1.0000 * Ratings.rating) AS average
FROM Track
JOIN Ratings ON Track.TrackId = Ratings.trackid
Group By Track.TrackId
But, you're also trying to pick up the Name at the same time. Doing that at that same time as a group by isn't as straightforward in SQL as you might wish. A 'correct' way is something like:
SELECT
Track.TrackId,
Average,
Name
FROM Track
INNER JOIN (
SELECT TrackId, AVG(1.0000 * Ratings.rating) AS average
FROM Ratings
Group By TrackId
) R
ON Track.TrackId = R.trackid

Using the SQL "IsNull()" command in NHibernate criteria in C#

I need to be able to use with NHibernate criteria, the SQL's IsNull() function in C#.NET. I don't need to use it with LINQ.
Meaning that Table1 has the following columns:
Name | Description
Table2 has the following columns:
OriginalDescription | TranslatedDescription
And Table1.Description = Table2.OriginalDescription.
How would I write the following SQL statement with NHibernate criteria:
SELECT Table1.Model, IsNull(Table2.TranslatedDescription, Table1.Description)
FROM Table1
LEFT JOIN Table2 ON Table2.OriginalDescription = Table1.Description
The SQL statement above will give me the Names, and TranslatedDescriptions if the TranslatedDescriptions exist, otherwise it will return the Descriptions, for the records.
There cannot be duplicates of OriginalDescription in the Table2.
The solution of the ISNULL could be expressed like this:
// here is the criteria of the "Entity1" and the join to the "Entity2"
var criteria = session.CreateCriteria("Entity1", "table1");
criteria.CreateAlias("Entity2", "table2");
// here we drive the SELECT clause
criteria.SetProjection(
Projections.ProjectionList()
.Add(Projections.Property("Model"))
.Add(Projections.SqlFunction("COALESCE", NHibernateUtil.String
, Projections.Property("table2.TranslatedDescription")
, Projections.Property("table1.Description")
))
);
// just a list of object arrays
var list = criteria.List<object[]>();
So, what we do here, is a call of the SqlFunction. In this case one of the out-of-the-box mapped in many Dialects coming with NHibernate (but we can even extend the dialect with custom ones, an example how to: Nhibernate count distinct (based on multiple columns))
Must note, that the JOIN Clause is coming from the mapping. So this Table2.OriginalDescription = Table1.Description must come from a mapped relation many-to-one

SQL 2 INNER JOINS with 3 tables

I've a question about a SQL query.. I'm building a prototype webshop in ASP.NET Visual Studio. Now I'm looking for a solution to view my products. I've build a database in MS Access, it consists of multiple tables.
The tables which are important for my question are:
Product
Productfoto
Foto
Below you'll see the relations between the tables
For me it is important to get three datatypes: Product title, price and image.
The product title, and the price are in the Product table. The images are in the Foto table.
Because a product can have more than one picture, there is a N - M relation between them. So I've to split it up, I did it in the Productfoto table.
So the connection between them is:
product.artikelnummer -> productfoto.artikelnummer
productfoto.foto_id -> foto.foto_id
Then I can read the filename (in the database: foto.bestandnaam)
I've created the first inner join, and tested it in Access, this works:
SELECT titel, prijs, foto_id
FROM Product
INNER JOIN Productfoto
ON product.artikelnummer = productfoto.artikelnummer
But I need another INNER JOIN, how could I create that? I guess something like this (this one will give me an error)
SELECT titel, prijs, bestandnaam
FROM Product
(( INNER JOIN Productfoto ON product.artikelnummer = productfoto.artikkelnummer )
INNER JOIN foto ON productfoto.foto_id = foto.foto_id)
Can anyone help me?
something like this should work:
SELECT Product.titel, Product.prijs, Foto.bestandnaam FROM Product INNER JOIN
(Foto INNER JOIN Productfoto ON Foto.[foto_id] = Productfoto.[foto_id]) ON
Product.[artikelnummer] = Productfoto.[artikelnummer];
One thing about the use of linking tables
The ProductFoto table allows for N-M relations between Product and Foto indeed. Is this what you really want/need? In other words, can one Foto belong to more than one Product? If not, put the Product_Id on the Foto table. If so,...
...let's discuss JOIN.
Say we have two tables, A and B. doing a
SELECT * FROM A, B
will give you all permutations of A's rows with B's rows. We could limit the resultset by adding a WHERE clause, like WHERE A.a='lekker hoor!', or a way cooler WHERE A.id=B.a_id. Which actually starts to look like a JOIN result!
Lets do a proper JOIN then:
SELECT * FROM A JOIN B ON A.id=B.a_id
JOINs actually come in LEFT OUTER, RIGHT OUTER and FULL INNER or FULL OUTER joins.
A LEFT JOIN (use of OUTER is optional) will contain all records in the left (first) table, even if there is no corresponding records(s) in the right (second) table.
A RIGHT JOIN obviously works the same way, but mirrored.
With a FULL OUTER JOIN both tables are optional (not quite the same as SELECT * FROM A, B though!).
A FULL INNER needs matching records from both tables (this is the default).
When you do want to do more than one JOIN, say
SELECT * FROM
A
JOIN B ON A.id=B.a_id
JOIN C ON B.id=C.b_id
You can think of the extra JOIN as joining on an intermediate table, formed by joining A and B, especially when mixing some LEFT/RIGHT/INNER/OUTER JOINs.
As to your question
Use something along the lines of
SELECT TOP (1) titel, prijs, bestandnaam
FROM
( -- this bracket is MS Access specific (and awkward)
Product
INNER JOIN Productfoto ON product.artikelnummer = productfoto.artikelnummer
) -- this one too
INNER JOIN foto ON productfoto.foto_id = foto.foto_id
to satisfy MS Access, use brackets around first two tables, see Ms-Access: Join 3 Tables
Normally no brackets required (you'll get to use them like this when you discover sexy sub-selects, for which the rule is: only use them if there is no alternative).
Because there are multiple matches in your ProductFoto table, there are multiple matches in your result. Use TOP 1 (or LIMIT 1, depending on your DB) to 'fix' this.
Veel success, en doe jezelf een plezier en switch to English!

Categories

Resources