Aggregate functions : the correct syntax in SQL query - aggregate

I have a table that contains Customer No_ and Amount on each row. I want to write a report that shows total amount by customer, by salesperson. I can inner join another table to get the salesperson. Just can't figure out the Customer No_ and Amount query.

I think you can just add sum(i.Amount) to your select and also to your group by. (Sorry, I don't have access to SQL Server at the moment to test this.)

Related

Npgsql - FULL OUTER JOIN on two unrelated tables

I have two tables, point_transactions which shows how users got and spent their in-app points, and wallet_transactions which shows how users got and spent their wallet money (real money). These two tables do not have direct relation with each other. They both have a created_on column which shows when they were created. I need to create a table that shows history of a user's transactions (both point and wallet). This table is sorted based on the creation time of the transaction and has paging, which means it's better to get paged result from database rather than loading all data into memory.
The following query gives me what I want:
select *,
case
when pt.id is null then wt.created_on
else pt.created_on
end as tx_created_on
from point_transactions as pt
full outer join wallet_transactions as wt on false
order by tx_created_on desc
Is there any way I can get this with EF Core?

PostgreSQL how to GROUP BY single field from returned table

So I have complicated query, to simplify let it be like
SELECT
t.*,
SUM(a.hours) AS spent_hours
FROM (
SELECT
person.id,
person.name,
person.age,
SUM(contacts.id) AS contact_count
FROM
person
JOIN contacts ON contacts.person_id = person.id
) AS t
JOIN activities AS a ON a.person_id = t.id
GROUP BY t.id
Such query works fine in MySQL, but Postgres needs to know that GROUP BY field is unique, and despite it actually is, in this case I need to GROUP BY all returned fields from returned t table.
I can do that, but I don't believe that will work efficiently with big data.
I can't JOIN with activities directly in first query, as person can have several contacts which will lead query counting hours of activity several time for every joined contact.
Is there a Postgres way to make this query work? Maybe force to treat Postgres t.id as unique or some other solution that will make same in Postgres way?
This query will not work on both database system, there is an aggregate function in the inner query but you are not grouping it(unless you use window functions). Of course there is a special case for MySQL, you can use it with disabling "sql_mode=only_full_group_by". So, MySQL allows this usage because of it' s database engine parameter, but you cannot do that in PostgreSQL.
I knew MySQL allowed indeterminate grouping, but I honestly never knew how it implemented it... it always seemed imprecise to me, conceptually.
So depending on what that means (I'm too lazy to look it up), you might need one of two possible solutions, or maybe a third.
If you intent is to see all rows (perform the aggregate function but not consolidate/group rows), then you want a windowing function, invoked by partition by. Here is a really dumbed down version in your query:
.
SELECT
t.*,
SUM (a.hours) over (partition by t.id) AS spent_hours
FROM t
JOIN activities AS a ON a.person_id = t.id
This means you want all records in table t, not one record per t.id. But each row will also contain a sum of the hours for all values that value of id.
For example the sum column would look like this:
Name Hours Sum Hours
----- ----- ---------
Smith 20 120
Jones 30 30
Smith 100 120
Whereas a group by would have had Smith once and could not have displayed the hours column in detail.
If you really did only want one row per t.id, then Postgres will require you to tell it how to determine which row. In the example above for Smith, do you want to see the 20 or the 100?
There is another possibility, but I think I'll let you reply first. My gut tells me option 1 is what you're after and you want the analytic function.

Update count in row after Insert

I'm completely new to SQL and have a question. I am using is PostgreSQL.
I have two tables called "employees" and "offices"
The table "employees" have a list of unique employees with each having an OfficeID (The office where they work).
What I want to do is to "count" the number of appearances of the Office_ID and take that count into the table "offices" where the "office_ID" have a column called "number_of_employees".
Being completely new to SQL the only thing I have managed to even come close to this is fore example.
SELECT COUNT(*)
FROM employees
WHERE office_id = 203
But this only selects and gives the sum of rows with the id "203" that has to be manually entered into "number of empolyees"
What I want is a trigger function that updates the field "number_of_empolyees" when a new record is inserted into the table "empolyees"
A view is the way to go here.
I am assuming since you're completely new to SQL, you're unsure how to make it work (Edit: just seen your comment after posting :^D) .
The correct way to count employees for each office is:
SELECT office_id, COUNT(*) as employeeCount
FROM employees
GROUP BY office_id
Note how your WHERE office_id = XXX has been replaced by a GROUP BY office_id in order to count employees for all offices in a single query.
That being done, we can use it inside the view.
Be careful about the JOIN: I believe in your schema, an office may have no employee (for instance, right after you created it or right before you delete it). We will handle that part with a LEFT JOIN.
CREATE VIEW OfficeWithEmployeeCount AS
SELECT Offices.*, EmployeeCount
FROM Offices
LEFT OUTER JOIN (SELECT office_id, COUNT(*) as EmployeeCount FROM Employees GROUP BY office_id) T
ON Offices.office_id = T.office_id
Note: to avoid having NULL returned in EmployeeCount for empty offices, you may want to write:
CREATE VIEW OfficeWithEmployeeCount AS
SELECT Offices.*, COALESCE(EmployeeCount,0)
FROM ...

How do I prevent removing duplicate records from my Access query results?

The Data
I'm working in MS Access 2013. I have two tables ('Import' and 'Import-Pay'). I have a query that combines data from the two.
Import-Pay contains transaction data from a client, which includes the occasional duplicate transaction record (example: customer buys something +$50, customer returns -$50, customer changes mind and buys it again +$50). Its rare, but it happens. My issue is, when creating my clients billing report (the query), since the client is only recording date of sale in the transaction I end up with TWO +$50 records in the Import-Pay table.
The Query
I am querying the transaction data and marrying it with secondary table information on the customers via the query below:
SELECT DISTINCTROW Import.[ACCOUNT#] AS [ACCOUNT#], [Import-Pay].[Account Number], [Import-Pay].[Name], [Import-Pay].[P TRANS DT], [Import-Pay].[P Trans Amt], [Import-Pay].[Total Account Balance]
FROM Import RIGHT JOIN [Import-Pay] ON Import.[CD#] = [Import-Pay].[Account Number]
GROUP BY Import.[ACCOUNT#], [Import-Pay].[Account Number], [Import-Pay].[Name], [Import-Pay].[P TRANS DT], [Import-Pay].[P Trans Amt], [Import-Pay].[Total Account Balance];
My Issue
The tables are RIGHT joined, so ALL records from my 'Import-Pay' table should be displayed... but for some reason the duplicate records of Import-Pay are lost after the query runs giving me a different total [Trans Amt].
Troubleshooting
I've double checked my table join to make sure that's not the issue.
I've tried removing the 'Group By' statement
I've removed the 'DISTINCTROW' function
I've messed with this for two days now and I'm out of ideas. A fresh set of eyes on the problem would be greatly appreciated!
Thanks!
You don't have any Aggregate functions, so get rid of the GROUP BY clause. Also remove DISTINCTROW.
Your Import-Pay table should have a Primary Key. Include this column (if it is a composite key, all columns) in the SELECT list.
If it doesn't have a Primary Key, create one (an AutoNumber column works fine).

Create a query to select two columns; (Company, No. of Films) from the database

I have created a database as part of university assignment and I have hit a snag with the question in the title.
More likely I am being asked to find out how many films each company has made. Which suggests to me a group by query. But I have no idea where to begin. It is only a two mark question but the syntax is not clicking in my head.
My schema is:
CREATE TABLE Movie
(movieID CHAR(3) ,
title CHAR(36),
year NUMBER,
company CHAR(50),
totalNoms NUMBER,
awardsWon NUMBER,
DVDPrice NUMBER(5,2),
discountPrice NUMBER(5,2))
There are other tables but at first glance I don't think they are relevant to this question.
I am using sqlplus10
The answer you need comes from three basic SQL concepts, I'll step through them with you. If you need more assistance to create an answer from these hints, let me know and I can try to keep guiding you.
Group By
As you mentioned, SQL offers a GROUP BY function that can help you.
A SQL Query utilizing GROUP BY would look like the following.
SELECT list, fields, aggregate(value)
FROM tablename
--WHERE goes here, if you need to restrict your result set
GROUP BY list, fields
a GROUP BY query can only return fields listed in the group by statement, or aggregate functions acting on each group.
Aggregate Functions
Your homework question also needs an Aggregate function called Count. This is used to count the results returned. A simple query like the following returns the count of all records returned.
SELECT Count(*)
FROM tablename
The two can be combined, allowing you to get the Count of each group in the following way.
SELECT list, fields, count(*)
FROM tablename
GROUP BY list, fields
Column Aliases
Another answer also tried to introduce you to SQL column aliases, but they did not use SQLPLUS syntax.
SELECT Count(*) as count
...
SQLPLUS column alias syntax is shown below.
SELECT Count(*) "count"
...
I'm not going to provide you the SQL, but instead a way to think about it.
What you want to do is select where the company matches and count the total rows returned. That count is the number of films made by the specified company.
Hope that points you in the right direction.
Select company, count(*) AS count
from Movie
group by company
select * group by company won't work in Oracle.