I have two tables(and their columns) in my DB:
CUSTOMERS(ID, FIRSTNAME, LASTNAME, ADDRESS);
ORDERS (ID, PRODUCT_NAME, PRODUCT_PRICE, DATE_ORDER DATE, ID_CUSTOMER, AMOUNT);
Here is what should I exactly do:
List the first and last names of the customers along with the count
of their orders.
List the first and last names of the customers and calculate the total sum of their orders.
Please make series of SELECTs and sort each one by FIRSTNAME and LASTNAME.
You could join the customers table with an aggregate query on the orders table:
SELECT firstname, lastname, num_orders, sum_orders
FROM customers
JOIN (SELECT id_customer, COUNT(*) AS num_orders, SUM(amount) AS sum_orders
FROM orders
GROUP BY id_customer) OR id_customer = id
ORDER BY 1, 2
Related
Employees table :
EmpID (Primary Key)
LastName
FirstName
Orders table :
OrderID (Primary Key)
CustID
EmpID
OrderDate
RequiredDate
ShippedDate
I need a query which returns EmpID, LastName, FirstName, total number of orders by employee, and total number of orders shipped late. An order is late if its ShippedDate is 5 days after RequiredDate. I got the late shipments by :
julianday(ShippedDate) - julianday(RequiredDate) >= 5
I thought to make two separate queries, one that takes a total count of the submissions and one for total count of late orders, then UNION them. I'm not getting the result I am looking for:
SELECT Employees.EmpId, Employees.LastName, Employees.FirstName, COUNT(*) as TotalCount, NULL
FROM Orders, Employees
WHERE Orders.EmpID = Employees.EmpID
GROUP BY LastName
UNION
SELECT Employees.EmpId, Employees.LastName, Employees.FirstName, NULL, COUNT(*) as LateCount
FROM Orders, Employees
WHERE Orders.EmpID = Employees.EmpID
AND julianday(ShippedDate) - julianday(RequiredDate) >= 5
GROUP BY LastName
I end up with offset null values on right side of the table :
TotalCount
NULL
17
NULL
NULL
25
etc.
What went wrong with my UNION? Why is the data offset and the column header wrong?
Is there a better approach?
"Is there a better approach?"
JOIN instead of UNION :
SELECT
Employees.EmpID,
Employees.LastName,
Employees.FirstName,
count(*) AS TotalCount,
sum(
julianday(Orders.ShippedDate) - julianday(Orders.RequiredDate) >= 5
) AS LateCount
FROM
Employees
JOIN Orders ON Orders.EmpID = Employees.EmpID
GROUP BY
Employees.EmpID
ORDER BY
TotalCount DESC,
LateCount DESC
Here is what my table looks like:
Here what I need:
I tried this code
SELECT DISTINCT(product_id),
SUM(quantity) OVER (PARTITION BY product_id) AS sumquantity
FROM ord1;
GROUP BY will do the trick in this case!
SELECT emp, name, product, SUM(quantity)
FROM ord1
GROUP BY emp, name, product
ORDER BY emp, name, product
Replace the column names with the ones from your database table.
I have table customer with columns country, customer_id and customer_name.
I need to order the mat table in angular by columns country, customer_id and customer_name, like in SQL query.
SELECT * FROM customers ORDER BY country, Customer-Name;
I have a table with names of countries. The country names are duplicated in the table. Eg say there are 8 rows in the table, 5 rows with country Germany and 3 with country UK. I want to get count the countries in the table (eg. I should get the number 2). But I am unable to come up with the query
I tried SELECT Country FROM Customers; but that will give me 8 rows. I tried SELECT DISTINCT Country FROM Customers; but that gives me 2 rows. I tried using count as SELECT DISTINCT Count(Country) FROM Customers; but I get 8 (probably because DISTINCT is applied on result set of SELECT Count(Country) FROM Customers; How could I get 2?
You can use distinct inside count:
select count(distinct country)
from customers;
Which is equivalent to:
select count(*)
from (
select distinct country
from customers
where country is not null
) t;
use inside distinct
SELECT count( distinct Country) FROM Customers
You can use distinct country within count as below:
SELECT count(DISTINCT country)
FROM customers;
You can use distinct country within count and group by country for getting country name as well:
SELECT count(1), country
FROM customers
GROUP BY country;
Here is one way to do this using analytic functions:
SELECT ROW_NUMBER() OVER (ORDER BY COUNT(*)) cnt
FROM customers
GROUP BY country
ORDER BY cnt DESC
LIMIT 1;
Let's say I have a table with columns:
CustomerNumber
Lastname
Firstname
PurchaseDate
...and other columns that do not change anything in the question if they're not shown here.
In this table I could have many rows for the same customer with different purchase dates (I know, poorly designed... I'm only trying to fix an issue for reporting, not really trying to fix the root of the problem).
How, in SQL, can I keep one record per customer with the latest date, and delete the rest? A group by doesn't seem to be working for my case
;with a as
(
select row_number() over (partition by CustomerNumber, Lastname, Firstname order by PurchaseDate desc) rn
from <table>
)
delete from a where rn > 1
This worked for me (on DB2):
DELETE FROM my_table
WHERE (CustomerNumber, Lastname, Firstname, PurchaseDate)
NOT IN (
SELECT CustomerNumber, Lastname, Firstname, MAX(PurchaseDate)
FROM my_table
GROUP BY CustomerNumber, Lastname, FirstName
)
SELECT CustomerNumber, Lastname, Firstname, MAX(PurchaseDate) LatestPurchaseDate
FROM Table
GROUP BY CustomerNumber, Lastname, Firstname
The MAX will select the highest (latest) date and show that date for each unique combination of the GROUP BY columns.
EDIT: I misunderstood that you wanted to delete records for all but the latest purchase date.
WITH Keep AS
(
SELECT CustomerNumber, Lastname, Firstname, MAX(PurchaseDate) LatestPurchaseDate
FROM Table
GROUP BY CustomerNumber, Lastname, Firstname
)
DELETE FROM Table
WHERE NOT EXISTS
(
SELECT *
FROM Keep
WHERE Table.CustomerNumber = Keep.CustomerNumber
AND Table.Lastname = Keep.Lastname
AND Table.Firstname = Keep.Firstname
AND Table.PurchaseDate = Keep.LastPurchaseDate
)