Query table columns from another table using the foreign key - sql

I am trying to get customer email and phonenumber in orders table when I have the order id.
The structure of the schema is below with customer id in orders table:
orders
id
date
item
refid
customerFk
customers
id
name
email
phonenumber
when I try to retrieve the customers phonenumber or email table from the order refId in SQL Server using
select
from order a
where a.custtomerFK.email
I get this error
Cannot call method on bigints
Please assist with the proper query.

The proper syntax is:
SELECT o.date, o.item, o.refid c.Name, c.email, c.phonenumber
FROM orders o
LEFT JOIN customers c ON o.customerFk = c.id
ORDER BY o.date, o.item, c.name

You can use this if you have customers for each order
SELECT orders.date, orders.item, orders.refid
, customers.Name, customers.email, customers.phonenumber
FROM orders
INNER JOIN customers ON orders.customerFk = customers.id

Related

SUBSELECT (SQL)

I have to tables. The first table (customers) shows data about the customers (id, firstname, lastname). The second table shows data about the orders (timestamp and customer id). So, i wanted to see the last order by a customer in my table "customers" and did a SUBSELECT and it worked.
SELECT id,firstname, lastname,
(SELECT timestamp FROM orders
WHERE customers.id = orders.customer_id
ORDER BY timestamp DESC LIMIT 1) AS last_order
FROM customers
WHERE (SELECT timestamp FROM orders
WHERE customers.id = orders.customer_id) IS NOT NULL
But, there are some customers who never ordered something and so is no value in the column "last_order". I am trying to filter these customers out with another SUBSELECT after the WHERE but i am failing. Can somebody help me?
The problem is with the second sub-query, it may return more than one value (one customer may have multiple orders); it should return only one value, so you may limit it by 1 as the following:
WHERE (SELECT timestamp FROM orders
WHERE customers.id = orders.customer_id Limit 1) IS NOT NULL
Another approach is to use Exists as the following:
SELECT id,firstname, lastname,
(SELECT timestamp_ FROM orders
WHERE customers.id = orders.customer_id
ORDER BY timestamp_ DESC LIMIT 1) AS last_order
FROM customers
WHERE exists (SELECT 1 FROM orders
WHERE customers.id = orders.customer_id);
Also, you can achieve the required result with a simple Join query as the following:
Select C.id,C.firstname, C.lastname, Max(O.timestamp_) AS last_order
From customers C
join orders O on
C.id=O.customer_id
Group By C.id,C.firstname, C.lastname
See a demo from db-fiddle.

How to sort customer names by items purchased in SQL

Sorry new to this but,
I need to sort customer names by total quantity of items purchased by them, in desc order.
the purchased amount in the table is known as Inv_number
I would need the customer name and than the sum. This is what it should be
Thanks
I don't know what your tables are named or what fields they have on them, so I'll give a generic example:
SELECT c.CUST_NAME AS "cust_name",
SUM(oi.QTY_PURCHASED) AS "sum"
FROM CUSTOMERS c
INNER JOIN ORDERS o
ON o.ID_CUSTOMERS = c.ID_CUSTOMERS
INNER JOIN ORDER_ITEMS oi
ON oi.ID_ORDERS = o.ID_ORDERS
GROUP BY c.CUST_NAME
ORDER BY SUM(oi.QTY_PURCHASED) DESC,
c.CUST_NAME ASC
db<>fiddle here
Should work this way - you have to join the tables for customerinfo (customer in this script) and the items purchased (order_items). For simplicity I only made an example with two tables. if the customer_id is present in a kind of "order" table, you have to join order_items -> order -> customer
SELECT
x.customer_name,
y.customer_amount
FROM customer x
INNER JOIN (
SELECT
customer_id,
SUM(order_amount) AS customer_amount
FROM order_items
GROUP BY customer_id
) y ON x.id = y.customer_id
ORDER BY y.customer_amount DESC;

Can I join the results from a like where clause, to another table

I would like to do a search on one table "Customers" using LIKE with a wild card and with these results JOIN on another "RECEIPTS" not sure how to achieve this, I am using an access database
ie
SELECT customercode, firstname, lastname FROM customers WHERE customercode LIKE *searchterm AS RESULTS
INNER JOIN receipts ON customers.customercode = receipts.customercode
I am not sure how to structure this query, joining the 2 before the WHERE seem very sluggish as there are many RECEIPTS matching CUSTOMERS. So I would like to CULL the set to just the matching customer first then join this to RECEIPTS on matching customer code.
Any help appreciated.
SELECT customercode, firstname, lastname FROM customers WHERE customercode LIKE *searchterm AS RESULTS
INNER JOIN receipts ON customers.customercode = receipts.customercode
I am currently using
SELECT Docketnumber, date, total, tblcustomer.customercode, firstname, lastname, businessname FROM tblreceipts INNER JOIN tblcustomer on tblreceipts.customercode = tblcustomer.customercode WHERE firstname like 'c%'
You can filter the customers and then join to receipts like this:
SELECT c.customercode, c.firstname, c.lastname
FROM (
SELECT * FROM customers
WHERE customercode LIKE '*searchterm'
) AS c INNER JOIN receipts AS r
ON c.customercode = r.customercode
You could use a join for relate the tables and filter the result from customers using your where condition
SELECT c.customercode
, c.firstname
, c.lastname
FROM customers c
INNER JOIN receipts r ON c.customercode = r.customercode
WHERE c.customercode LIKE '%your_value%'
If you only want information from the customers table, I would recommend EXISTS:
SELECT c.customercode, c.firstname, c.lastname
FROM customers as c
WHERE c.customercode LIKE "*searchterm" AND
EXISTS (SELECT 1
FROM receipts as r
WHERE c.customercode = r.customercode
);
Very importantly: This does not return multiple rows if a customer has multiple receipts. You would use a join if you wanted columns from the receipts table, but that is not the case with your question.

Join data from three related tables

In Postgres I have the following 4 tables
user (
id,
name
);
order(
id,
user_id
)
service(
id,
name
);
order_to_service(
id,
order_id,
service_id
price
);
I want to write a query to see User name , amount of orders of this user and how much money he spend on all orders
Example:
name amount price
Albert 100 3200
This is my query
select u.name , count(o.user_id),sum(ots.price)
from orders o inner join users u on u.id=o.user_id
inner join order_to_service ots on ots.order_id = o.id
where(o.user_id is not null) group by u.name
This is my result:
"Аlbert";55;29978
Accodring to this result user with name Albert has 55 orders
But using this query
select count(*) from orders where user_id = (select id from users where name like 'Albert')
Result is 33
What's wrong with my first query?
If the relationship between Orders table and Order_to_service table is one to many, then you would need to sum up the price per order in Order_to_service table before joining with the Orders table. Try this:
select u.name , count(o.user_id),sum(ots.price_tot)
from orders o inner join users u on u.id=o.user_id
inner join ( select order_id, sum(price) as price_tot
from order_to_service
group by order_id ) ots
on ots.order_id = o.id
where (o.user_id is not null) group by u.name

Sql query to display records that appear more than once in a table

I have two tables, Customer with columns CustomerID, FirstName, Address and Purchases with columns PurchaseID, Qty, CustomersID.
I want to create a query that will display FirstName(s) that have bought more than two products, product quantity is represented by Qty.
I can't seem to figure this out - I've just started with T-SQL
You could sum the purchases and use a having clause to filter those you're interested in. You can then use the in operator to query only the customer names that fit these IDs:
SELECT FirstName
FROM Customer
WHERE CustomerID IN (SELECT CustomerID
FROM Purchases
GROUP BY CustomerID
HAVING SUM(Qty) > 2)
Please try this, it should work for you, according to your question.
Select MIN(C.FirstName) FirstName from Customer C INNER JOIN Purchases P ON C.CustomerID=P.CustomersID Group by P.CustomersID Having SUM(P.Qty) >2
Please try this:
select c.FirstName,p.Qty
from Customer as c
join Purchase as p
on c.CustomerID = p.CustomerID
where CustomerID in (select CustomerID from Purchases group by CustomerID having count(CustomerID)>2);
SELECT
c.FirstName
FROM
Customer c
INNER JOIN Purchases p
ON c.CustomerId = p.CustomerId
GROUP BY
c.FirstName
HAVING
SUM(p.Qty) > 2
While the IN suggestions would work they are kind of overkill and more than likely less performant than a straight up join with aggregation. The trick is the HAVING Clause by using it you can limit your result to the names you want. Here is a link to learn more about IN vs. Exists vs JOIN (NOT IN vs NOT EXISTS)
There are dozens of ways of doing this and to introduce you to Window Functions and common table expressions which are way over kill for this simplified example but are invaluable in your toolset as your queries continue to get more complex:
;WITH cte AS (
SELECT DISTINCT
c.FirstName
,SUM(p.Qty) OVER (PARTITION BY c.CustomerId) as SumOfQty
FROM
Customer c
INNER JOIN Purchases p
ON c.CustomerId = p.CustomerId
)
SELECT *
FROM
cte
WHERE
SumOfQty > 2