How to Order SQL Query using two columns? - sql

accounts table
----------------
id name
10 ABC Company
11 XYZ Company
12 LMN Company
13 EFG Company
14 JKL Company
.. ...........
.. ...........
accounts_opportunities table
-----------------------
id opportunity_id account_id deleted
1 1 11 0
2 2 11 0
3 3 12 0
4 4 12 0
5 5 13 0
6 6 14 0
. . .. .
. . .. .
opportunities table
-----------------
id name amount
1 Opp 1 100
2 Opp 2 50
3 Opp 3 500
4 Opp 4 600
5 Opp 5 200
6 Opp 6 1000
I am trying to select top 20 accounts from above tables. And I written following query for
that,
SELECT TOP 20 COUNT(*) as number_of_opportunities,
(
SELECT accounts.name
FROM accounts
WHERE accounts.id=accounts_opportunities.account_id
) as account_name
FROM accounts_opportunities
JOIN opportunities ON opportunities.id = accounts_opportunities.opportunity_id
WHERE accounts_opportunities.deleted != '1'
GROUP BY accounts_opportunities.account_id
ORDER BY number_of_opportunities DESC
And above query gives following output;
Account name Number of Opportunities
------------ -----------------------
ABC Company 3
XYZ Company 2
LMN Company 2
EFG Company 1
JKL Company 1
XYZ and LMN have same numbers opportunities, but if I calculate total amount of XYZ opportunities are less than LMN total amount. Also JKL has higher amount than EFG.
My question is how to order this query from number_of_opportunities and then total opportunity amount. can someone please give me a guide..
Expected Output
Account name Number of Opportunities
------------ -----------------------
ABC Company 3
LMN Company 2
EFG Company 1
JKL Company 1
XYZ Company 2

Try this:
SELECT TOP 20 a.name, COUNT(*) AS [Number of Opportunities]
FROM accounts AS a
INNER JOIN accounts_opportunities AS ao ON a.id = ao.account_id
INNER JOIN opportunities AS o ON o.id = ao.opportunity_id
WHERE ao.deleted != 1
GROUP BY a.id, a.name
ORDER BY COUNT(*) DESC, SUM(amount) DESC
So, you can add SUM(amount) in the ORDER BY clause with DESC. This will place accounts with higher amount sums on top of other accounts, in case of a tie in COUNT(*).

Related

Select from same column but multiples values and number of records with one specific value

ID Customer Status
1 ABC 1
2 ABC 2
3 ABC 3
4 ABC 1
5 PQR 1
6 PQR 2
7 PQR 3
8 XYZ 1
9 XYZ 3
I want to select customer who has both values "status=1" and "Status=2' and also total number of entry of same customer with Status=1.
So the result will be,
Customer totalEntryStatus1
ABC 2
PQR 1
How can I do this.
Thankyou !
select Customer, count(case when status = 1 then 1 end) totalEntryStatus1
from table
where Status in (1,2)
group by Customer
having count(distinct Status) = 2

Query to display unique comments based on certain conditions

TABLE DEFINITION
ColumnName Comments
CustomerID INT
SequenceNo INT
Comments VARCHAR(MAX)
CUSTOMER TABLE
CustomerID SequenceNo Comments
1 1 ABC D
1 2 CDE
1 3 ABC
1 4 ABC D
1 5 CDE
1 6 abc
2 7 ABC DEF
2 8
2 9 ABC DEF
2 10 DEF
2 11 XYZ 123
2 12 ABC
3 13 PQ RST
OUTPUT
CustomerID SequenceNo Comments
1 3 ABC
1 4 ABC D
1 5 CDE
1 6 abc
2 8
2 9 ABC DEF
2 10 DEF
2 11 XYZ 123
2 12 ABC
3 13 PQ RST
Records should be filtered by
1. Display only Unique Comments from Customer Table for all the customers,
2. If Comments are same then display the row which has maximum SequenceNo
This assumes you are using a case sensitive collation
SELECT CustomerID,
MAX(SequenceNo) AS SequenceNo,
Comments
FROM yourTable
GROUP BY CustomerID,Comments
ORDER BY CustomerID,MAX(SequenceNo)
If you are not using a case sensitive collation, then try this:
SELECT CustomerID,
MAX(SequenceNo) AS SequenceNo,
Comments COLLATE SQL_Latin1_General_CP1_CS_AS
FROM yourTable
GROUP BY CustomerID,Comments COLLATE SQL_Latin1_General_CP1_CS_AS
ORDER BY CustomerID,MAX(SequenceNo)
You can use window functions for this:
select c.*
from (select c.*,
row_number() over (partition by CustomerId, Comments
order by SequenceNo desc) as seqnum
from comments c
) c
where seqnum = 1;

Multiply newly entered row with another column value and find Total Sum in SQL

I have 4 tables here, I need to multiply newly entered row value in a table with another row and find the total sum using CustomerId:
CustomerTable:
CustomerId Name EmailId
-------------------------
1 Paul r#r.com
2 John J#j.com
LoyaltyPointTable:
LoyaltyPointsId LoyaltyType Points
---------------------------------------
1 Registration 10
2 Loginstatus 1
3 Downloading 10
4 Redemming 1
5 Sharing 20
6 Refer 10
LoyaltyDetailsTable:
LoyaltyDetailsId LoyaltyPointsId CustomerId Dates
-------------------------------------------------
1 1 1 2015-01-22
2 2 1 2015-01-22
3 3 2 2015-01-22
4 3 1 2015-01-22
5 4 1 2015-01-22
6 4 1 2015-01-24
7 5 1 2015-01-24
This query works fine for the total sum for each LoyaltyType
SELECT
LoayaltyPointsTable.LoyaltyType,
COUNT(CustomerTable.CustomerId) AS UserActions,
SUM(LoayaltyPointsTable.Points) AS TotalPoints
FROM
LoayaltyPointsTable
JOIN
LoyaltyDetailsTable ON LoayaltyPointsTable.LoyaltyPointsId = LoyaltyDetailsTable.LoyaltyPointsId
JOIN
CustomerTable ON CustomerTable.CustomerId = LoyaltyDetailsTable.CustomerId
WHERE
CustomerTable.CustomerId = 1
GROUP BY
LoyaltyDetailsTable.CustomerId ,LoayaltyPointsTable.LoyaltyType
below RedeemPointsTable is created with relation to row redeeming in LoyaltyPointTable:
RedeemPointsTable:
RedeemPointsId CustomerId ShopName BillNo Amount
------------------------------------------------
1 1 Mall x 4757 100
3 1 Mall y SH43 50
4 1 Mall x 7743 10
6 1 Mall x s34a 60
What I am expecting is before calculating the total sum, I want column Amount sum (100+50+10+60) * 1 in Redeeming in LoyaltyPointTable to be added with total points for each CustomerId
Expected output
LoyaltyType UserActions TotalPoints
-------------------------------------
Downloading 1 10
Loginstatus 1 1
Redemming 4 (100+50+10+60)*1(here using Amount in RedeemPointsTable)
Refer 1 10
Registration 1 10
Sharing 1 20
User actions count is 4, it is based on the Amount he entered in RedeemPointsTable
Should I need to make changes in adding a foreign key column in RedeemPointsTable or can you point out my mistake?
Any help would be great.
This is the query which returns desired result:
SELECT
LoyaltyPointTable.LoyaltyType,
CASE
WHEN LoyaltyPointTable.LoyaltyPointsId=4 THEN (SELECT COUNT(amount) FROM RedeemPointsTable where CustomerId=1)
ELSE COUNT(CustomerTable.CustomerId)
END as UserActions,
CASE
WHEN LoyaltyPointTable.LoyaltyPointsId=4 THEN (SELECT SUM(amount) FROM RedeemPointsTable where CustomerId=1)*Points
ELSE SUM(LoyaltyPointTable.Points)
END as TotalPoints
FROM
LoyaltyPointTable
JOIN
LoyaltyDetailsTable ON LoyaltyPointTable.LoyaltyPointsId = LoyaltyDetailsTable.LoyaltyPointsId
JOIN
CustomerTable ON CustomerTable.CustomerId = LoyaltyDetailsTable.CustomerId
WHERE
CustomerTable.CustomerId = 1
GROUP BY
LoyaltyDetailsTable.CustomerId ,LoyaltyPointTable.LoyaltyType
You can check it here

How can I write a query with 2 states?

I have table Customer:
Id Code Name
1 100 John
2 200 Jack
3 300 Mike
4 400 Betty
And table SaleType:
Id Code Name
1 1000 cash
2 2000 cheque
3 3000 free
And a table that describe which customer has which sale type named SaleType_Customer
Id SaleTypeID CustomerID
1 1 1
2 1 2
3 2 1
4 2 3
I want to write a query that takes the SaleTypes of a customer. But if the customer is not in table SaleType_Customer the query returns all of SaleTypes. How can I write this query?
My query:
SELECT SaleType.ID, SaleType.Code, SaleType.Name
FROM SaleType left outer join SaleType_Customer on SaleType.Id = SaleType_Customer.SaleTypeID
Where SaleType_Customer.CustomerID= 1
I want the result for John (id=1):
Id Code Name
1 1000 cash
2 2000 cheque
And for Betty (id=4) is complete because she is not in SaleType_Customer:
Id Code Name
1 1000 cash
2 2000 cheque
3 3000 free
How should I write my query?
SELECT distinct SaleType.ID, SaleType.Code, SaleType.Name
FROM Customer left join SaleType_Customer
on CustomerID = Customer.Id
,SaleType
where (SaleTypeID = SaleType.Id or SaleTypeID is NULL)
and Customer.ID= 4;
Here is the SQLFiddle
SELECT SaleType.ID, SaleType.Code, SaleType.Name
FROM SaleType
WHERE NOT EXISTS (SELECT *
FROM SaleType_Customer
WHERE SaleType_Customer.Customerid = 4)
UNION
SELECT SaleType.ID, SaleType.Code, SaleType.Name
FROM SaleType
INNER JOIN SaleType_Customer
ON SaleType_Customer.Saletypeid = SaleType.Id
WHERE SaleType_Customer.Customerid = 4
Sqlfiddle sample (oracle)

Need hierarichal data from 3 tables in SQL Server

I have following tables:
UserMaster:
UserId Int, UserName Varchar(200),AddedBy Int
UserId EmpName AddedBy
1 admin 0
2 SubAdmin1 1
3 SubAdmin2 1
4 Vikas 2
5 Mohit 4
6 Atul 5
7 Vishal 6
8 Mani 3
9 Sunny 8
SalesMaster:
SalesId Int, UserId Int (FK_UserMaster_UserId) , Price Int
SalesId UserId Price
1 1 100
2 2 200
3 3 300
4 4 500
5 5 100
6 6 200
7 7 111
8 8 222
9 9 333
Case 1: Now I want the price total of all the users who are under the one particular user and its own price also.
Means If i consider UserId=1 , Then the price will be calculated for all users where Column value in AddedBy=1
and their lower level employees.
Means the total Price of users will be calulated for the users having UserId are: 1,2,3,4,5,6,7,8,9.
Case 2: Similarly, If i want to calculate the total price under UserId=3(SubAdmin2) then the total price from the salesMaster will be calculated for the Users having UserId are: 3,8,9
The Result of first Case should be:
UserId Price
1 2066
The Result of Second Case should be:
UserId Price
3 300+222+333
Please Help
Thanks & Regards
Nitin
with cte as (
select #UserId as UserId
union all
select um.UserId
from UserMaster as um
inner join cte as c on c.UserId = um.AddedBy
)
select sum(s.Price)
from cte as c
inner join SalesMaster as s on s.UserId = c.UserId
sql fiddle demo