Below is my SCHEMA with create scripts:
CREATE TABLE transaction
(tran_id INT,
tran_seq_nbr INT,
Tran_sold_amt INT,
Card_no VARCHAR(20),
Payment_Method VARCHAR(20),
Card_type VARCHAR(20),
Tran_Date VARCHAR(20));
Insert into transaction Table:
INSERT INTO transaction (tran_id, tran_seq_nbr,Tran_sold_amt, Card_no,
Payment_Method, Card_type, Tran_Date)
VALUES(1010,1,10,'123','Card','Visa', '2019-01-01'),
(1010,2,20,'124','Card','MasterCard', '2019-01-01'),
(2020,1,30,'125','Card','Visa', '2019-01-31'),
(2020,2,40,Null,'Cash',Null,'2019-01-31'),
(10101,1,100,'123','Card','Visa','2019-02-01'),
(1011,1,100,Null,'Cash',Null,'2019-02-01');
CREATE TABLE Customer(Cust_id INT, Cust_name VARCHAR(20));
INSERT INTO Customer (Cust_id,Cust_name)
VALUES(1,'JANE DOE'),
(2,'JOHN DOE');
CREATE TABLE Credit_card (Card_no INT, Cust_id INT, Card_type VARCHAR(20));
INSERT INTO Credit_card (Card_no,Cust_id,Card_type)
VALUES(123,1,'Visa'),
(124,1,'MasterCard'),
(125,2,'Visa'),
(126,2,'MasterCard'),
(127,3,'Visa'),
(128,4,'American Express');
My SOLUTION is below
Select customer.cust_name, customer.cust_id, credit_card.card_type,
credit_card.card_no,sum(transaction.Tran_sold_amt) AS AMOUNT,
YEAR (transaction.tran_date) AS YEAR
from customer
join credit_card
on customer.cust_id=credit_card.cust_id
join transaction
on credit_card.card_no = transaction.card_no
group by credit_card.card_type, credit_card.card_no, YEAR,customer.cust_name;
My PROBLEM is:
I am not able to find the cash entry rest of the entries are visible
Please help is with the fix and thanks.
Welcome to SO!.
The thing is your are using a so called INNER join, meaning that it only show the records that are related.
Your Cash entries are not linked to the Credit_Card table, so they will not be shown. If you want to retrieve them as well, you could use this:
SELECT [Transaction].[Payment_Method]
,ISNULL([Transaction].Card_type,'') AS [Card Type]
,ISNULL(credit_card.card_no,'') AS [Card Number]
,SUM(ISNULL([transaction].Tran_sold_amt,0)) AS AMOUNT
,YEAR([Transaction].tran_date) AS [YEAR]
,ISNULL(Customer.Cust_name,'') AS [Customer Name]
FROM [transaction]
LEFT OUTER JOIN credit_card
on credit_card.card_no = [transaction].card_no
LEFT OUTER JOIN [Customer]
on customer.cust_id=credit_card.cust_id
GROUP BY [Transaction].[Payment_Method]
,[Transaction].Card_type
,credit_card.card_type
,credit_card.card_no
,YEAR([transaction].tran_date)
,customer.Cust_id
,customer.cust_name;
By the way, this is T-SQL.
I used OUTER JOIN, so that all records from the transaction table are used, even if they are not related to the other 2 tables.
Related
I need to do the following:
From each branch, find the manager names and the #customers they are managing and the total deposit balance of the customers they manage
My database looks like this
drop table branch;
CREATE TABLE branch (
BNO NUMBER(1,0),
MANAGER_NAME VARCHAR(6),
Salary NUMBER(6,0),
MGRSTARTDATE TIMESTAMP (2)
);
INSERT INTO branch VALUES
(1,'BOB',100000,'19-JUN-2001');
INSERT INTO branch VALUES
(2,'CHRIS',150000,'01-Jan-2005');
INSERT INTO branch VALUES
(3,'ANGELA',90000,'22-May-1998');
INSERT INTO branch VALUES
(4,'KIM',90000,'29-May-1996');
drop table account;
CREATE TABLE account (
ACC NUMBER(3,0),
CNAME VARCHAR(4),
BNO NUMBER(1,0),
BALANCE NUMBER(4,0)
);
INSERT INTO account VALUES
(101,'LISA',1,100);
INSERT INTO account VALUES
(102,'LISA',2,500);
INSERT INTO account VALUES
(103,'TOM',1,400);
INSERT INTO account VALUES
(104,'JOHN',3,1200);
INSERT INTO account VALUES
(105,'TOM',3,900);
All I have so far and don't know what to do next is
SELECT MANAGER_NAME
FROM branch;
I think I need to do some type of join but don't know how.
Try this
select br.manager_name, acc.cname from account acc
left join branch br
ON acc.bno = br.bno
And the below will sum balance that manager manage
select br.manager_name, acc.cname, sum(acc.balance) from account acc
left join branch br
ON acc.bno = br.bno
group by br.bno, br.manager_name
You'll want to use a OUTER JOIN (this is the same as a LEFT/RIGHT join). An outer join takes all values from the one table and adds data from the second table matching on a key. The key you'd use to match is the "BNO" value -- hoangnh's example covers this
For reference, the other type of join is an INNER JOIN which wouldn't work since that would only return values with key matches in both tables (in your example, doing an inner join would exclude BNO=4 from the final result. Doing an outer join would have BNO=4 included with nulls for the customer values)
Here is my table
CREATE TABLE Customer
(
ID CHAR(50),
Customer_FName CHAR(50),
Customer_Lname CHAR(50)
);
CREATE TABLE Buying
(
Customer_ID CHAR(50),
Product_ID CHAR(50),
Order_Time CHAR(50)
);
CREATE TABLE Product
(
ID CHAR(50),
Name CHAR(50),
Address CHAR(50)
);
I am trying to find all customers who bought a product with their company's address in 'Burwood' and list the customer's ID, names, product ID, product name and product address
Select
Buying.Customer_ID, Buying.Product_ID, Product.ID,
Product.Name, Customer.ID,
Customer.Customer_FName, Customer.Customer_Lname
from
((Buying
inner join
Product on Buying.Product_ID = Product.ID)
inner join
Customer on Buying.Customer_ID = Customer.ID)
where
Product.Address like '%Burwood%';
I want to combine three table but It shows 'no rows selected'.
I also give a sample data table
Any reason why you have chosen CHAR as the datatype for all columns of all tables? For CHAR based columns, DBs tend to pad the values up to the column width defined. That said, it is not why you are not getting result. You may want to check if during insert you are adding any extra space or non-printable characters in IDs resulting into failed inner joins.
I suggest change the fields to VARCHAR instead, validate your inserts and then query just as I demonstrated below. You will start getting result, as I am..
CREATE TABLE Customer (
ID varchar(50),
Customer_FName varchar(50),
Customer_Lname varchar(50)
);
CREATE TABLE Buying (
Customer_ID varchar(50),
Product_ID varchar(50),
Order_Time varchar(50)
);
CREATE TABLE Product (
ID varchar(50),
Name varchar(50),
Address varchar(50)
);
insert into customer values('10001', 'John', 'Smith');
insert into Buying values('10001', '772', '2016/09/01');
insert into Product values('772', 'Telephone', '22 Ave, Burwood');
select b.product_id, p.name, b.customer_id, c.customer_fname, c.customer_lname
from buying b
join product p on b.product_id = p.id
join customer c on b.customer_id = c.id
where lower(p.address) like '%burwood%'
Please try this, it works for me:
Select B.Customer_ID, B.Product_ID, P.ID, P.Name, C.ID, C.Customer_FName, C.Customer_Lname
from Buying B
INNER JOIN Product P ON B.Product_ID = P.ID
INNER JOIN Customer C ON B.Customer_ID = C.ID
WHERE P.Address LIKE '%Burwood%'
Try this:
SELECT C.*,B.*, P.*
FROM Customer C,Buying B, Product P
WHERE B.Product_ID=P.ID
AND B.Customer_ID=C.ID
AND P.Address LIKE '%Burwood%';
For my CIS class, I have SQL project, and this is the first time I'm working with SQL, doing okay but I can't do one of the queries. Any help would be greatly appreciated.
This is what I tried:
Select cno, cname
from customer
where
)
)
)
Just use two IN clauses, one for 'Financial Accounting', one for 'Cost Accounting'.
Select cno, cname
from customer
where cno in
(
select cno
from salesorder
where ono in
(
select ono
from orderline
where bno in (select bno from book where bname = 'Financial Accounting')
)
)
and cno in
(
select cno
from salesorder
where ono in
(
select ono
from orderline
where bno in (select bno from book where bname = 'Cost Accounting')
)
);
Rob M's solution is more elegant, whereas above query should be more along the lines what you've learned so far.
You aren't exactly clear on whether the customer needs to have ordered both books in one order or across multiple orders. I'll assume the latter, based on the data provided.
Your answer returns customers who ordered either (or both) of those books. You say you want customers who order both books. Also, it's hard to keep your code straight when nesting several subqueries. Most people prefer joins.
This query should work for you.
select cno,cname from customer where cno in (
select o.cno
from salesorder o
inner join orderline ol on o.ono=ol.ono
inner join book b on b.bno=ol.bno
where b.bname in ('Financial Accounting', 'Cost Accounting')
group by o.cno
having count(distinct b.bno) = 2 -- Require both separate books, not 2 of one book or the other
)
Here is a complete example in SQL Server:
declare #book table (bno int, bname varchar(50))
insert #book (bno,bname) values
(10501,'Forensic Accounting')
,(10704,'Financial Accounting')
,(10933,'Cost Accounting')
declare #orderline table (ono int, bno int)
insert #orderline (ono,bno) VALUES
(1020,10501)
,(1020,10502)
,(1020,10503)
,(1020,10504)
,(1021,10605)
,(1022,10605)
,(1022,10704)
,(1023,10879)
,(1023,10988)
,(1024,10502)
,(1024,10988)
,(1026,10933)
,(1027,10933)
,(1028,10933)
,(1028,10965)
,(1029,10933)
,(1029,10965)
,(1029,10988)
,(1030,10965)
declare #salesorder table (ono int, cno int)
insert #salesorder (ono,cno) VALUES
(1020,23511)
,(1021,23513)
,(1022,23513)
,(1023,23512)
,(1024,23511)
,(1025,23511)
,(1026,23511)
,(1027,23512)
,(1028,23512)
,(1029,23513)
,(1030,23511)
declare #customer table (cno int, cname varchar(20))
insert #customer (cno,cname) values
(23511,'a')
,(23512,'b')
,(23513,'c')
,(23514,'d')
,(23515,'e')
,(23516,'f')
,(23517,'g')
,(23518,'h')
select cno,cname from #customer where cno in (
select o.cno
from #salesorder o
inner join #orderline ol on o.ono=ol.ono
inner join #book b on b.bno=ol.bno
where b.bname in ('Financial Accounting', 'Cost Accounting')
group by o.cno
having count(distinct b.bno) = 2 -- Require both separate books, not 2 of one book or the other
)
I'm not even sure this is possible, but I have an order table (online store). Within this table, the shipping and billing address columns are ID's which correspond with the address table.
For E.g.
OrderID ShippingAddressID BillingAddressID
201800194 21183 21182
The Address table then lists the address information.
AddressID Address1 City RegionCode
21182 123 Somewhere Dr Hometown1 Florida
21183 456 Elsewhere Rd Hometown2 Florida
I'd like the resulting listing to show something similar to this:
OrderID BillingAddress1 BillingCity BillingRegionCode ShippingAddress1 ShippingCity ShippingRegionCode
201800194 123 Somewhere Dr Hometown1 Florida 456 Elsewhere Rd Hometown2 Florida
Is this even possible?
Thanks..
Join the address table twice. Example with your data below.
CREATE TABLE #Orders (OrderID int, ShippingAddressId int, BillingAddressId int)
CREATE TABLE #Address (AddressID int, Address1 varchar(100), City varchar(100), RegionCode varchar(100))
INSERT INTO #Orders (OrderID, ShippingAddressId, BillingAddressId) VALUES
(201800194 , 21183, 21182)
INSERT INTO #Address (AddressID, Address1, City, RegionCode) VALUES
(21182, '123 Somewhere Dr', 'Hometown1', 'Florida'),
(21183, '456 Elsewhere Rd', 'Hometown2', 'Florida')
SELECT
ORD.OrderID,
BILL.Address1 AS 'BillingAddress1',
BILL.City AS 'BillingCity',
BILL.RegionCode AS 'BillingRegionCode',
SHIP.Address1 AS 'ShippingAddress1',
SHIP.City AS 'ShippingCity',
SHIP.RegionCode AS 'ShippingRegionCode'
FROM
#Orders AS ORD
LEFT OUTER JOIN #Address AS SHIP
ON ORD.ShippingAddressId = SHIP.AddressID
LEFT OUTER JOIN #Address AS BILL
ON ORD.BillingAddressId = BILL.AddressID
DROP TABLE #Orders
DROP TABLE #Address
Lets assume your Tables are Order, Address.
Select A.OrderID, B1.Address1 As 'BillingAddress1', B1.City As 'BillingCity', B1.RegionCode As 'BillingRegionCode', B2.Address1 As 'ShippingAddress1', B2.City As 'ShippingCity', B2.RegionCode As 'ShippingRegionCode'
FROM Order AS A
Left Join Address AS B1 On A.BillingAddressID = B1.AddressID
Left Join Address As B2 On A.ShippingAddressID = B2.AddressID
Hope this Helps
Yes you can achieve it using join like this -
SELECT OrderId, Billing.Address1 As BillingAddress1, Shipping.Address1 AS
ShippingAddress1, ... other column
FROM dbo.Order
LEFT JOIN dbo.Address AS Billing ON Order.BillingAddressID = Billing.AddressID
LEFT JOIN dbo.Address AS Shipping ON Order.ShippingAddressID = Shipping.AddressID
Here is the current query I am running.
select c.customer_name, c.city, c.credit_limit, sum(ol.quoted_price)
from customer c, order_line ol, (select order_num from order_line where part_num = 'AT94') t1
where ol.order_num = t1.order_num and customer_num in ( select customer_num
from orders
where order_num in (select t1.order_num
from order_line,(select order_num from order_line where part_num = 'AT94') t1
INNER JOIN
(select order_num from order_line where part_num = 'BV06') t2
on t1.order_num = t2.order_num
where t1.order_num = order_line.order_num
group by t1.order_num))
group by t1.order_num, c.customer_name, c.city, c.credit_limit
The current output I am receiving is:
I wish to obviously remove the duplication located in the output and currently have no idea how to do so. I have tried using unique in the multiple sub-queries with no success.
Any help is great! Thanks.
Here is the database creation.
CREATE TABLE CUSTOMER
(
CUSTOMER_NUM CHAR(3) PRIMARY KEY,
CUSTOMER_NAME CHAR(35) NOT NULL,
STREET CHAR(15),
CITY CHAR(15) DEFAULT 'Ottawa',
PROVINCE CHAR(3),
ZIP CHAR(5),
BALANCE DECIMAL(8,2),
CREDIT_LIMIT DECIMAL(8,2),
REP_NUM CHAR(2)
CONSTRAINT CHK_Limit CHECK (CREDIT_LIMIT >= BALANCE)
);
CREATE TABLE ORDERS
(
ORDER_NUM CHAR(5) PRIMARY KEY,
ORDER_DATE DATE,
CUSTOMER_NUM CHAR(3)
);
CREATE TABLE PART
(
PART_NUM CHAR(4) PRIMARY KEY,
DESCRIPTION CHAR(15),
ON_HAND DECIMAL(4,0),
CLASS CHAR(2),
WAREHOUSE CHAR(1),
PRICE DECIMAL(6,2)
);
CREATE TABLE ORDER_LINE
(
ORDER_NUM CHAR(5),
PART_NUM CHAR(4),
NUM_ORDERED DECIMAL(3,0),
QUOTED_PRICE DECIMAL(6,2),
PRIMARY KEY (ORDER_NUM, PART_NUM)
);
The solution I would like where the order does not matter for the column:
Al's.. | Barrhaven | 7500.00 | 21.95
John.. | Toronto | 10000.00 | 311.95
All data used. Quite a large sum of text. Just decided Pastebin instead of making this question that much longer.
https://pastebin.com/ASBzqcJq
You basically need to see which customer has bought both of parts_numb AT94 and BV06. The issue you're facing is that your query returning duplicated rows, this is because your query already have some redundancy. Which made me go back and check the giving results manually to get the correct results out of the sample that you've provided.
SELECT
ol.ORDER_NUM,
c.customer_name,
c.city,
c.credit_limit,
sum(ol.quoted_price)
FROM #order_line ol
INNER JOIN #Orders o ON o.order_num = ol.order_num
JOIN (SELECT ORDER_NUM FROM #ORDER_LINE WHERE part_num = 'AT94') t1 ON t1.ORDER_NUM = o.ORDER_NUM
JOIN (SELECT ORDER_NUM FROM #ORDER_LINE WHERE part_num = 'BV06') t2 ON t2.ORDER_NUM = o.ORDER_NUM
INNER JOIN #customer c ON c.customer_num = o.customer_num
WHERE
ol.ORDER_NUM IN(t1.ORDER_NUM)
AND ol.ORDER_NUM IN(t2.ORDER_NUM)
GROUP BY
ol.ORDER_NUM,
c.customer_name,
c.city,
c.credit_limit
SQLFiddle
Hope this will save your day
I can see that your result set already has distinct records. Your result set does not have any two rows with exactly same values. What is the output you are expecting? I am not sure what your requirement is. But I think the join between customer number in Customer table and Customer number in Orders table is missing.
Are you trying to do something like this?
select C.customer_name, C.city, C.credit_limit, sum(OL.quoted_price)
from CUSTOMER C
join ORDERS O ON C.Customer_num=O.Customer_num
join ORDER_LINE OL on O.Order_num=Ol.Order_num
WHERE part_num in('AT94','BV06')
group by C.customer_name, C.city, C.credit_limit;