I need to make a sql - sql

**
SELECT clientName, orderID FROM
Orders INNER JOIN clients ON orders.clientID = clients.clientID;
**
I can show every client and each of their orders. Help me correct my SQL syntax, so I am showing the number of orders for each client?
I also want my results to be ordered alphabetically by client name,
please write a new SQL syntax for me!

SELECT clientName, COUNT(*)
FROM Orders INNER JOIN clients ON orders.clientID = clients.clientID
GROUP BY clientName
ORDER BY clientName

You can use aggregation:
select c.clientName, count(*) no_orders
from clients c
inner join orders o on o.clientID = c.clientID
group by c.clientID, c.clientName
Notes:
table aliases make the query easier to read and write
adding the id of the client to the group by clause handles the possibility that different clients might have the same name
in general, you want to avoid camel case identifiers (ClientName) and use snake case instead (client_name): from database perspective, identifiers are case insensitive (unless quoted)

Related

SQL Server INNER JOIN and GROUP BY

In sql server I'm trying to group by each sales people some infos as follow:
I have 2 tables: Positions and Clients
In Positions table, I have the following columns: Client_Id, Balance, Acquisition_Cost and in the Clients table I use the following columns: Client_Id and Sales_person.
I want to group by Sales_person (Clients table) the Client_id, Balance, Acquisition_Cost (Positions table)
I tried this:
SELECT Positions.Client_ID, Positions.Balance, Positions.Acquisition_cost
FROM Positions
INNER JOIN Clients ON Positions.Client_ID = Clients.Client_ID
GROUP BY Sales_person
It gives me "Positions.Client_ID is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause".
I precise I'm pretty new on SQL so that does not ring that much a bell to me.
You need to add Positions.Client_ID in the GROUP BY Clause, since the select expects this column if you really do not want Positions.Client_ID in the select, then no need to add in the GROUP BY Clause
For any column in your SELECT that you aren't including in the GROUP BY, you need to use some kind of aggregate function (MAX, SUM, etc.) on the column. So you could write it like this:
SELECT Positions.Client_ID
, Clients.Sales_person
, SUM(Positions.Balance) Balance_Sum,
, SUM(Positions.Acquisition_cost) Acquisition_Cost_Sum
FROM Positions
INNER JOIN Clients ON Positions.Client_ID = Clients.Client_ID
GROUP BY Positions.Client_ID
, Clients.Sales_person
If you only want the totals by Sales_person and not client_ID, you could just remove client_id from the SELECT AND GROUP BY:
SELECT Clients.Sales_person
, SUM(Positions.Balance) Balance_Sum,
, SUM(Positions.Acquisition_cost) Acquisition_Cost_Sum
FROM Positions
INNER JOIN Clients ON Positions.Client_ID = Clients.Client_ID
GROUP BY Clients.Sales_person
SELECT a.Client_ID, b.Sales_person, SUM(a.Balance) as Balance_Sum,SUM(a.Acquisition_cost) as Acquisition_Cost_Sum FROM Positions as a INNER JOIN Clients as b ON a.Client_ID = b.Client_ID GROUP BY a.Client_ID, b.Sales_person
Thanks all of you guys, here's the code that works for me in this case:
SELECT Positions.Client_Id, Clients.Sales_person, SUM(Positions.Balance) as sum_balance_impacted, SUM(Positions.Acquisition_cost) as sum_acquisition_cost
FROM Positions
INNER JOIN Clients ON Positions.Client_Id= Clients.Client_Id
GROUP BY Clients.Sales_person, Positions.Client_Id```

SQL Query + Join

I have 2 tables - Client, Jobs,
Client - clientID,clientName,clientCity
Bricklayers - jobNum, clientID, startDate
Now I need to query the database to list me all clients in 3 cities (Charlotte, Raleigh, Wilmington) and if they have a job on the Bricklayers table also list their jobNum(s) and startDate
I'm completely unsure what approach to take to this problem as I've never needed a query like this. I know I need a join and tried an inner join on the clientID in both columns but kept receiving syntax errors.
Try this
SELECT c.clientID, c.clientName, b.jobNum, b.startDate
FROM Client c
INNER JOIN Bricklayers b ON c.clientID = b.clientID
WHERE c.clientCity IN ('Charlotte','Raleigh','Wilmington');

SQL Server - getting duplicate rows with different queries

I'm trying to get a count of child records (addresses) for each customer. I have 2 queries and I'm wondering if they're the same:
SELECT
a.AddressId, c.CustomerID, COUNT(*) AS NumDuplicates
FROM
Customers C
INNER JOIN
Addresses a ON c.AddressID = a.AddressID
GROUP BY
c.CustomerID, a.AddressId
ORDER BY
NumDuplicates DESC
SELECT
c.CustomerID,
(SELECT COUNT(*)
FROM Addresses a
WHERE a.AddressID = c.AddressID) AS AddressCount
FROM
Customers c
ORDER BY
AddressCount desc
If they're not, what's the difference? If they are which is more efficient?
The two queries are different, because the first only returns customers that have at least one match in the address table. The second returns all customers, even those with no match and having AddressId is NULL.
The equivalent first query is:
SELECT c.CustomerID, COUNT(a.AddressId) AS NumDuplicates
FROM Customers C LEFT JOIN
Addresses a
ON c.AddressID = a.AddressID
GROUP BY c.CustomerID
ORDER BY NumDuplicates DESC;
As for performance, you should try them out. There are reasons why either might be faster. The second avoids having to do aggregation, but does have a correlated subquery. However, SQL Server has some tricks for speeding joins and aggregation. I would guess that the correlated subquery version is faster, but I might be wrong for your data and server.

SQL Query to find MAX Date

I have some software that uses dBase4 for its database. I am attempting to construct a report using fields from 3 tables (Customer, Service & History).
In all of the tables the ACCOUNT field is the same. The 'Customer' and the 'Service' table only have one one record for each Customer. The 'History' table has multiple records for each Customer.
I need to write a query so that only the record with the MAX date in 'History.BILLTHRU' is returned for each Customer. The code below returns all of the records for each Customer in the History table:
SELECT Customer.ACCOUNT,
Customer.FIRSTNAME,
(more fields...),
History.ACCOUNT,
History.BILLTHRU,
Service.ACCOUNT,
Service.OFFERCODE
FROM "C:\Customer.dbf" Customer
INNER JOIN "C:\History.dbf" History
ON (Customer.ACCOUNT = History.ACCOUNT)
INNER JOIN "C:\Service.dbf" Service
ON (Customer.ACCOUNT = Service.ACCOUNT)
WHERE Customer.STATUS = "A"
ORDER BY Customer.LAST_BUS_NAME
Use a sub-query and a group by:
SELECT Customer.ACCOUNT,
Customer.FIRSTNAME,
(more fields...),
History.ACCOUNT,
History.BILLTHRU,
Service.ACCOUNT,
Service.OFFERCODE
FROM "C:\Customer.dbf" Customer
INNER JOIN (SELECT ACCOUNT, MAX(BILLTHRU) AS BILLTHRU
FROM "C:\History.dbf"
GROUP BY ACCOUNT) History
ON (Customer.ACCOUNT = History.ACCOUNT)
INNER JOIN "C:\Service.dbf" Service
ON (Customer.ACCOUNT = Service.ACCOUNT)
WHERE Customer.STATUS = "A"
ORDER BY Customer.LAST_BUS_NAME
I like to use common table expressions (CTEs). Subqueries are good, but breaking it out like this sometimes makes it easier to keep separate.
with GetMaxDate as (
select account, max(billthru) as MaxBillThru
from "C:\History.dbf"
group by account
)
SELECT Customer.ACCOUNT,
Customer.FIRSTNAME,
(more fields...),
GetMaxDate.ACCOUNT,
GetMaxDate.MaxBillThru,
Service.ACCOUNT,
Service.OFFERCODE
.....
from FROM "C:\Customer.dbf" Customer
INNER JOIN GetMaxDate on customer.ACCOUNT = GetMaxDate.Account
INNER JOIN "C:\Service.dbf" Service
ON (Customer.ACCOUNT = Service.ACCOUNT)
WHERE Customer.STATUS = "A"
ORDER BY Customer.LAST_BUS_NAME
EDIT: This is a SQL Server function. I'm leaving it in case it can help you or someone else. I'll delete it if it just clouds the issue.

Difference b/w putting condition in JOIN clause versus WHERE clause

Suppose I have 3 tables.
Sales Rep
Rep Code
First Name
Last Name
Phone
Email
Sales Team
Orders
Order Number
Rep Code
Customer Number
Order Date
Order Status
Customer
Customer Number
Name
Address
Phone Number
I want to get a detailed report of Sales for 2010. I would be doing a join. I am interested in knowing which of the following is more efficient and why ?
SELECT
O.OrderNum, R.Name, C.Name
FROM
Order O INNER JOIN Rep R ON O.RepCode = R.RepCode
INNER JOIN Customer C ON O.CustomerNumber = C.CustomerNumber
WHERE
O.OrderDate >= '01/01/2010'
OR
SELECT
O.OrderNum, R.Name, C.Name
FROM
Order O INNER JOIN Rep R ON (O.RepCode = R.RepCode AND O.OrderDate >= '01/01/2010')
INNER JOIN Customer C ON O.CustomerNumber = C.CustomerNumber
JOINs must reflect the relationship aspect of your tables. WHERE clause, is a place where you filter records. I prefer the first one.
Make it readable first, table relationships should be obvious (by using JOINs), then profile
Efficiency-wise, the only way to know is to profile it, different database have different planner on executing the query
Wherein some database might apply filter first, then do the join subsquently; some database might join tables blindly first, then execute where clause later. Try to profile, on Postgres and MySQL use EXPLAIN SELECT ..., in SQL Server use Ctrl+K, with SQL Server you can see which of the two queries is faster relative to each other