sql query with two tables having reference key - sql

I have two tables:
Discounts(disid primary key)
Cust(custid primary key, disid ref discount(disid))
Now I need a query to get custid having all disid(discount coupons) and the customer may contain the same disid more than once.

select custid, count(distinct disid) from cust
group by custid
having count(*) = (select count(*) from discounts)

SELECT COUNT(DISTINCT D.disid) FROM CUST C
INNER JOIN DISCOUNTS D ON D.disid=C.disid GROUP BY D.disid

try either of this solutions:
SELECT a.custid, COUNT(a.disid) totalCoupon
FROM cust a
INNER JOIN discounts b
ON b.disid = a.disid
GROUP BY a.custid
or
SELECT a.custid, COUNT(a.disid) totalCoupon
FROM cust a
INNER JOIN discounts b
ON b.disid = a.disid
GROUP BY a.custid
HAVING COUNT(a.disid) > 1 -- customers having the same (but more than 1)
-- CouponID will only be shown here

Related

SQL 2 Rows into 1

Below is a SQL script to see how many customers purchased both products, as well as how many customers purchased either of the two products.
I would like to be able to return a result set with one column for the first product, one column for the second, one column for Count with Both, and one column for Count with Either.
Instead it returns a column for each of the counts and a single NULL column for the ProductID.
SELECT
COUNT(DISTINCT b.CustomerID) AS "Count with Both",
COUNT(DISTINCT c.CustomerID) AS "Count with Either",
b.ProductID
FROM
LocationCode z
LEFT JOIN
(SELECT DISTINCT ProductID, CustomerID
FROM LocationCode a
WHERE a.ProductID IN ('MP040') AND a.ProductID IN ('OG010')) b ON z.CustomerID = b.CustomerID
LEFT JOIN
(SELECT DISTINCT ProductID, CustomerID
FROM LocationCode b
WHERE b.ProductID IN ('MP040', 'OG010')) c ON z.CustomerID = c.CustomerID
GROUP BY
b.ProductID
If I understand correctly, you can use a self-join and aggregation. The following does what you want for all pairs of products:
with cp as (
select customerid, productid,
count(*) over (partition by customerid) as num_customers
from locationcode
group by customerid, productid
)
select cp1.productid, cp2.productid, cp1.cnt as cnt1, cp2.cnt as cnt2,
count(*) as both
from cp cp1 join
cp cp2
on cp1.customerid = cp2.customerid and
cp1.productid < cp2.productid
group by cp1.productid, cp2.productid, cp1.cnt, cp2.cnt ;
You can of course add where filters if you only want results for certain products.

Select sum from

I am trying to get the sum of all the rows associated with each customer and join on them.
However I am finding that if no rows exist it leaves out the customer completely.
I would prefer if the sum was zero. How would I achieve this.
Here is the SQL statement:
SELECT
Id, DebitSum
FROM
Customers
JOIN
(SELECT
SUM(Amount) DebitSum, CustomerId
FROM
Purchases
WHERE
Completed IS NULL
GROUP BY
CustomerId) p ON p.CustomerId = Id;
Using SQL Server, if it matters.
Just use LEFT JOIN:
SELECT c.Id, COALESCE(p.DebitSum, 0)
FROM Customers c LEFT JOIN
(SELECT SUM(p.Amount) as DebitSum, p.CustomerId
FROM Purchases p
WHERE p.Completed IS NULL
GROUP BY CustomerId
) p
ON p.CustomerId = c.Id;
This would normally be written without the subquery:
SELECT c.Id, COALESCE(SUM(p.Amount), 0) as DebitSum
FROM Customers c LEFT JOIN
Purchases p
ON p.CustomerId = c.Id;
WHERE p.Completed IS NULL
GROUP BY c.Id
You could use LEFT JOIN:
SELECT Id, COALESCE(DebitSum,0) AS DebitSum
FROM Customers
LEFT JOIN (
SELECT SUM(Amount) DebitSum, CustomerId
FROM Purchases
WHERE Completed IS NULL
GROUP BY CustomerId
) p ON p.CustomerId = Id;
Try this:
SELECT Id, DebitSum
FROM Customers
LEFT JOIN (
SELECT SUM(Amount) DebitSum, CustomerId
FROM Purchases
WHERE Completed IS NULL
GROUP BY CustomerId
) p ON p.CustomerId = Id;
Your doing a JOIN which means it has to exist in both tables/data sets. Changing it to LEFT JOIN only requires it to be in the First table and not the one after the LEFT JOIN
You can also use subquery only:
select id, (select coalesce(sum(p.Amount), 0)
from Purchases p
where p.CustomerId = c.id and p.Completed IS NULL
) as DebitSum
from Customers c
group by id;
SELECT SUM(Amount) DebitSum, CustomerId
there is no AS after the information? select sum(amount) as debitsum, customerid
try this
SELECT c.Id, COALESCE(p.DebitSum, 0) as DebitSum
FROM Customers c LEFT JOIN Purchases p
on c.Id = p.CustomerId
where p.completed is null

left join two tables on a non-unique column in right table

I have two tables in sql server and i wanna select and join some data from these table.the first tables have some customer like:
---------------
customer id
Dave 1
Tom 2
---------------
and second table i table of purchases that includes list of last purchases with cost and which customer bought that Product:
------------------
product date customer id
PC 1-1-2000 1
phone 2-3-2000 2
laptop 3-1-2000 1
------------------
i wanna select first table (customers info) with last date of their purchases!
i tried left join but that doesn't give me last purchases becuase customer id is not unique in second table! how can i do this function with SQL server query? Regards
If you just want the max date, use aggregation. I would recommend a left join for customers who have made no purchases:
select c.customer, c.id, max(p.date)
from customers c left join
purchases p
on c.id = p.customer_id
group by c.customer, c.id;
Use the not exists clause for the win!
select c.customer, p.*
from Customer as c
inner join Purchase as p
on p.customer_id = c.id
where not exists (
select 1
from Purchase as p2
where p2.customer_id = p.customer_id
and p2.date > p.date
)
I think you can use inner join and group by
select table1.customer, table1.id, table.max(date)
from table1
inner join table2 on table1.id = table2.id
group by table1.customer, table1.id

Row value from another table

I have a table that is having 2 duplicate rows (total of 3 rows), so I used the code below to get the duplicate value in the column
SELECT CustNo, COUNT(*) TotalCount
FROM Rental
GROUP BY CustNo
HAVING COUNT(*) > 1
ORDER BY COUNT(*) DESC
So once I get the repeated value, I need to get the CustNo derived as duplicate from the customer table. How do I go about taking this value and using it in the select statment all in the same query.
I also have the select statement prepared like this.
Select * from Customer where CustNo = 'T0002';
Thanks.
Select * from Customer
where CustNo IN
(
SELECT CustNo
FROM Rental
GROUP BY CustNo
HAVING COUNT(*) > 1
)
You can use join:
SELECT c.*
FROM (SELECT CustNo, COUNT(*) TotalCount
FROM Rental
GROUP BY CustNo
HAVING COUNT(*) > 1
) cc JOIN
Customer c
on cc.CustNo = c.CustNo;
Select C.* from Customer C RIGHT JOIN (
SELECT CustNo
FROM Rental
GROUP BY CustNo
HAVING COUNT(*) > 1) D
ON C.CustNo = D.CustNo
You can also try this,
With tblDups as(
select CustNo,count(CustNo) as TotalCount from a_rental
Group by CustNo
Having count(CustNo) >1)
select b.* from a_rental b
inner join tblDups a on a.CustNo = b.Custno

Repeated elements counting for Sql datatables queries

I have 2 tables: an Order table and an orderDetails table.
I have written a inner join:
SELECT Order.id
FROM Order
INNER JOIN orderDetails
ON Order.id=orderDetails.id
I have got the output as:
id
100
100
100
101
101
From the above data, I want the count of each record output as:
id count
100 3
101 2
How would I do this?
Select OrderId , Count(*) as [Count]
from OrderDetials
Group By OrderId
OrderId will be a foreing key column referencing Order.Id column of Order Table
If your orderDetails.id references Order.id column This will be the query.
Select id , Count(*) as [Count]
from OrderDetials
Group By id
SELECT o.id, COUNT(*)
FROM Order o
JOIN orderDetails od ON o.id=od.id
GROUP BY o.id
You need to use the COUNT aggregate and the GROUP BY clause.
SELECT Order.id, COUNT(DISTINCT orderDetails.id)
FROM Order
INNER JOIN orderDetails ON Order.id=orderDetails.orderId
GROUP BY Order.id
It also looks like you need o alter the join condition slightly.
Use Group by
SELECT Order.id, count(*) as Count
FROM Order
INNER JOIN orderDetails
ON Order.id=orderDetails.id Group by Order.id