SQL query for converting column values in row dynamically - sql

I am new to SQL so don't know much if you can help me out for eliminating duplicates from my query 1 or help me to transpose query 2
Old query 1: I already tried below query but some duplicate values were returned:
select
ROW_NUMBER() OVER (ORDER BY count(case when TransactionType = 1 then 1 else null end) desc) AS 'td','',
Warehouse as 'td','',
Createdate as 'td','',
count(case when TransactionType = 1 then 1 else null end) as 'td','',
count(case when TransactionType = 5 then 1 else null end) as 'td','',
count(case when TransactionType = 6 then 1 else null end) as 'td','',
cast(round(sum(localamount),8) as decimal(18,2))as 'td',''
from
PaymentTrn (nolock)
where
CreateDate = cast(convert(varchar(8),getdate() -1,112) as int)
group by
Warehouse, CreateDate
order by
count(case when TransactionType = 1 then 1 else null end) desc
Then I tried count(distinct case when TransactionType = 1 then 1 else null end) but is giving only 1.
For query 2 (shown here next), have 3 (useful) columns in DB invoice-type, transaction-type and warehouse from which I need to fetch data.
IMPORTANT: invoice number has duplicates so I need to use distinct
because I am getting duplicate values I modify the query, now I need to convert "no column name " column to row
Current output for a query is:
warehouse no column name
1700 3
1700 6
1700 9
query 2:
select warehouse,count(distinct(invoicenumber))
from PaymentTrn (nolock)
where CreateDate = cast(convert(varchar(8),getdate() -305,112) as int) and TransactionType = 1
group by Warehouse,CreateDate
union all
select warehouse,count(distinct(invoicenumber))
from PaymentTrn (nolock)
where CreateDate = cast(convert(varchar(8),getdate() -305,112) as int) and TransactionType = 5
group by Warehouse,CreateDate
union all
select warehouse,count(distinct(invoicenumber))
from PaymentTrn (nolock)
where CreateDate = cast(convert(varchar(8),getdate() -305,112) as int) and TransactionType = 6
group by Warehouse,CreateDate
the expected result should need to be:
warehouse transactiontype=1 transactiontype=5 transactiontype=6
1700 3 6 9

I think you simply want conditional aggregation with count(distinct). You seem to want to count invoice numbers:
select row_number() over (order by count(distinct case when TransactionType = 1 then invoicenumber end) desc) AS td, '',
Warehouse as td, '',
Createdate as td, '',
count(distinct case when TransactionType = 1 then invoicenumber end) as td, '',
count(distinct case when TransactionType = 5 then invoicenumber end) as td, '',
count(distinct case when TransactionType = 6 then invoicenumber end) as td, '',
cast(round(sum(localamount), 8) as decimal(18,2)) as td, ''
from PaymentTrn
where CreateDate = cast(convert(varchar(8),getdate() -1, 112) as int)
group by Warehouse, CreateDate
order by 1;

Here's your queries.
Query 1:
select t2.rownum as 'td',''
, t1.Warehouse as 'td',''
, t1.Createdate as 'td',''
, t2.cnt as 'td',''
, t3.cnt as 'td',''
, t4.cnt as 'td',''
, cast(round(sum(t1.localamount),8) as decimal(18,2))as 'td',''
from
PaymentTrn t1
left join
(select ROW_NUMBER() OVER (ORDER BY count(1) desc) as rownum, Warehouse
from
PaymentTrn (nolock)
where TransactionType = 1 and CreateDate = cast(convert(varchar(8),getdate() -1,112) as int)
group by Warehouse) t2 on t2.Warehouse = t1.Warehouse
left join
(select count(1) as cnt, Warehouse
from
PaymentTrn (nolock)
where TransactionType = 5 and CreateDate = cast(convert(varchar(8),getdate() -1,112) as int)
group by Warehouse) t3 on t3.Warehouse = t1.Warehouse
left join
(select count(1) as cnt, Warehouse
from
PaymentTrn (nolock)
where TransactionType = 6 and CreateDate = cast(convert(varchar(8),getdate() -1,112) as int)
group by Warehouse) t4 on t4.Warehouse = t1.Warehouse
where
t1.CreateDate = cast(convert(varchar(8),getdate() -1,112) as int)
order by t2.rownum desc
Query 2:
select t1.warehouse, count(distinct(t1.invoicenumber)) as TType1, t2.cnt as TType2, t3.cnt as TType3
from PaymentTrn t1
left join
(select Warehouse, count(distinct(invoicenumber)) as cnt from PaymentTrn
where CreateDate = cast(convert(varchar(8),getdate() -305,112) as int) and TransactionType = 1 group by customer_code) t2
on t2.Warehouse = t1.Warehouse
left join
(select Warehouse, count(distinct(invoicenumber)) as cnt from PaymentTrn
where CreateDate = cast(convert(varchar(8),getdate() -305,112) as int) and TransactionType = 1 group by customer_code) t3
on t3.Warehouse = t1.Warehouse
where t1.CreateDate = cast(convert(varchar(8),getdate() -305,112) as int) and t1.TransactionType = 1
group by t1.Warehouse, t2.TType2, t3.TType3

Related

Insert records from multiple rows of table to multiple columns of other table

I have an existing table structure with sample data like
Id
BookingId
Value
TypeId
AddedTime
1
100
10
T1
2021-03-22 08:51:52.6333333
2
100
20
T2
2021-03-22 08:50:55.8133333
3
100
30
T3
2021-03-22 08:50:22.1033333
4
200
50
T1
2021-03-22 08:50:22.1033333
5
200
60
T2
2021-03-22 08:50:22.1000000
6
200
70
T3
2021-03-22 08:50:22.0800000
and now data model is changed and it becomes like
Id
BookingId
Type1Value
Type2Value
Type3Value
AddedTime
Please help me what would be query to copy data from previous table to new table.
Output should be something like
Id
BookingId
Type1Value
Type2Value
Type3Value
AddedTime
1
100
10
20
30
2
200
50
60
70
I tried:
select BookingId
, Type1Value = max(case when RN=1 then Value else null end)
, Type2Value = max(case when RN=2 then Value else null end)
, Type3Value = max(case when RN=3 then Value else null end)
from (
select *
, rn = Row_Number() over (Partition By TypeId Order by AddedTime)
from Values_M
) a
where rn <= 3
group by BookingId
This will gives you the required result using conditional case expression.
Using row_number() to generate new running number Id
select Id = row_number() over (order by BookingId),
BookingId = BookingId,
Type1Value = max(case when TypeId = 'T1' then Value end),
Type2Value = max(case when TypeId = 'T2' then Value end),
Type3Value = max(case when TypeId = 'T3' then Value end),
AddedTime = min(AddedTime)
from Values_M
group by BookingId
dbfiddle
select BookingId, min(T1) as Type1Value, min(T2) as Type2Value, min(T3) as Type3Value
from table1
pivot (sum(value) for Typeid in (T1,T2,T3)) as PivotTable
group by BookingId
You can use row_number() and self join.
with cte as (
select Id, BookingId, [Value], TypeId, AddedTime
, row_number() over (partition by BookingId order by id asc) rn
from Values_M
)
select C1.rn, C1.BookingId, C1.[Value] Type1Value, C2.[Value] Type2Value, C3.[Value] Type3Value, C1.AddedTime
from cte C1
inner join cte C2 on C2.BookingId = C1.BookingId and C2.rn = 2
inner join cte C3 on C3.BookingId = C1.BookingId and C3.rn = 3
where C1.rn = 1
order by BookingId asc;

SQL return last 30 records on the same year

In my query I want to return only the records that saved in last 30 days within same year but my query returns all the records that happened in last 30 days from today's month and day regardless of the year. I don't know what the reason
I tried the condition in smaller query and it gives right result.
select top 10000
cb.billNo , MAX(cb.subCategoryID) subCategory ,
Max(cb.cateogryID) categoryID ,
MAX(tracking.date ) trackingDate,
Max(Station.Code) Dest,Max(cb.picesCount) PieceCount,
Max(case when cb.productCount > 1 then 1 else 0 end) isMultiProduct ,
Max(case when tt.ID = 1 and (cb. subCategoryID = 65 or cb.
subCategoryID
= 56) then 1 else 0 end) isReceived,
from CustomerBillss cb
join Tracking on cw.billNo = Tracking.billNo
join trackingtype tt on Tracking.TrackingTypeID = tt.ID
join Station on cb.destinationStationID = Station.ID
where
tracking.date > dateadd(dd,-30,cast(getdate() as date))
--(YEAR(tracking.Date) = YEAR(GETDATE()) AND
--tracking.Date >= DATEADD(day,-30,GETDATE()))
AND
cb. cateogryID in (1, 3)
AND Tracking.TrackingTypeID not in (8 , 4 ,20)
AND cb.subCategoryID != 30 or (
subCategoryID = 30 and cb.DestinationStationID = tracking.StationID)
group by cb.billNo;
Just uncomment the year filter in your select
select top 10000
cb.billNo , MAX(cb.subCategoryID) subCategory ,
Max(cb.cateogryID) categoryID ,
MAX(tracking.date ) trackingDate,
Max(Station.Code) Dest,Max(cb.picesCount) PieceCount,
Max(case when cb.productCount > 1 then 1 else 0 end) isMultiProduct ,
Max(case when tt.ID = 1 and (cb. subCategoryID = 65 or cb.
subCategoryID
= 56) then 1 else 0 end) isReceived,
from CustomerBillss cb
join Tracking on cw.billNo = Tracking.billNo
join trackingtype tt on Tracking.TrackingTypeID = tt.ID
join Station on cb.destinationStationID = Station.ID
where
tracking.date > dateadd(dd,-30,cast(getdate() as date))
(YEAR(tracking.Date) = YEAR(GETDATE()) AND
--tracking.Date >= DATEADD(day,-30,GETDATE()))
AND
cb. cateogryID in (1, 3)
AND Tracking.TrackingTypeID not in (8 , 4 ,20)
AND cb.subCategoryID != 30 or (
subCategoryID = 30 and cb.DestinationStationID = tracking.StationID)
group by cb.billNo;

How to merge two particular rows into single row and reaming rows are same using stored procedure SQL Server 2012

I have data like this. first row of Id 1 from particular time period and second row of id 1 is another time period. so now want to combined id and name which are same in the two time periods reaming are same.if there is no orders from that time period its should be display 0 or null.
Id Name Qty Price
----------------------
1 Rose 4 540
1 Rose 1 640
2 Lilly 5 550
2 Lilly 18 360
3 Grand 2 460
3 Grand 10 360
4 lotus 0 0
4 Lotus 9 580
now I want data like this..
Id Name Qty Price
4 540
1 rose
1 640
5 550
2 Lilly
18 360
2 460
3 Grand
10 360
0 0
4 Lotus
9 580
This is my procedure
create PROCEDURE [dbo].[Sp_Orders]
(
#Startdate varchar(30),
#Enddate varchar(30),
#Startdate1 varchar(30),
#Enddate1 varchar(30)
)
--[Sp_Orders] '03/01/2016','03/15/2016','02/01/2016','02/28/2016'
AS
BEGIN
---First Duration----
SELECT DISTINCT
op.ProductId as id, op.Price as Prc,
sc.SubCategoryName as ScName,
COUNT(op.ProductId) AS Qty,
ROUND(SUM(op.Price * op.Quantity), 0) AS Revenue,
FROM
orderdetails od
INNER JOIN
(SELECT DISTINCT
Orderid, Productid, ProductFeatures, Price, Quantity
FROM
OrderProducts) op ON od.Orderid = op.Orderid
INNER JOIN
products p ON p.productid = op.productid
INNER JOIN
subcategory sc ON sc.subcategoryid = p.subcategoryid
WHERE
CONVERT(datetime, CONVERT(varchar(50), od.DeliveryDate, 101)) BETWEEN #Startdate AND #Enddate
GROUP BY
op.ProductID, op.Price, sc.SubCategoryName
---Second Duration----
SELECT DISTINCT
op.ProductID AS id, op.Price AS Prc,
sc.SubCategoryName AS ScName,
COUNT(op.ProductId) AS Qty,
ROUND(SUM(op.Price * op.Quantity), 0) AS Revenue,
FROM
orderdetails od
INNER JOIN
(SELECT DISTINCT
Orderid, Productid, ProductFeatures, Price, Quantity
FROM
OrderProducts) op ON od.Orderid = op.Orderid
INNER JOIN
products p ON p.productid = op.productid
INNER JOIN
subcategory sc ON sc.subcategoryid = p.subcategoryid
WHERE
CONVERT(datetime, CONVERT(varchar(50),od.DeliveryDate,101)) BETWEEN #Startdate1 AND #Enddate1
GROUP BY
op.ProductID, op.Price, sc.SubCategoryName
END
From what I understood from your Question and Comments:
Schema for your case
SELECT * INTO #TAB FROM(
SELECT 1 ID, 'ROSE' NAME, 4 QTY, 540 PRICE
UNION ALL
SELECT 1 , 'ROSE' , 1 , 640
UNION ALL
SELECT 2 , 'LILLY' , 5 , 550
UNION ALL
SELECT 2 , 'LILLY' , 18 ,360
UNION ALL
SELECT 3 , 'GRAND' , 2 , 460
UNION ALL
SELECT 3 , 'GRAND' , 10 ,360
UNION ALL
SELECT 4 , NULL,NULL,NULL
UNION ALL
SELECT 4 , 'LOTUS' , 9 , 580
) AS A
And the Logic to display is as below
SELECT CASE WHEN SNO=1 THEN CAST(ID AS VARCHAR(250)) ELSE '' END ID,
CASE WHEN SNO=1 THEN ISNULL(NAME,'') ELSE '' END NAME,ISNULL(Qty,0)Qty
,ISNuLL(Price,0)Price FROM (
SELECT ROW_NUMBER() Over(partition by Name, Id ORDER BY (SELECT 1)) SNO
,ID, NAME , Qty, Price, ID AS ID2 FROM #TAB
)AS A
ORDER BY ID2, NAME DESC
Try this from your Procedure. And may need to do type cast based on your actual datatypes
CREATE PROCEDURE [DBO].[SP_ORDERS]
(
#STARTDATE VARCHAR(30),
#ENDDATE VARCHAR(30),
#STARTDATE1 VARCHAR(30),
#ENDDATE1 VARCHAR(30)
)
--[SP_ORDERS] '03/01/2016','03/15/2016','02/01/2016','02/28/2016'
AS
BEGIN
SELECT CASE WHEN SNO=1 THEN CAST(ID AS VARCHAR(250)) ELSE '' END ID,CASE WHEN SNO=1 THEN ISNULL(SCNAME,'') ELSE '' END NAME,ISNULL(QTY,0)QTY,ISNULL(REVENUE,0)PRICE FROM (
SELECT ROW_NUMBER() OVER(PARTITION BY SCNAME, ID ORDER BY (SELECT 1)) SNO, ID, SCNAME , QTY, REVENUE, ID AS ID2 FROM (
SELECT DISTINCT OP.PRODUCTID AS ID,OP.PRICE AS PRC,SC.SUBCATEGORYNAME AS SCNAME,COUNT(OP.PRODUCTID) AS QTY, ROUND(SUM(OP.PRICE * OP.QUANTITY), 0) AS REVENUE
FROM ORDERDETAILS OD INNER JOIN
(SELECT DISTINCT ORDERID,PRODUCTID,PRODUCTFEATURES,PRICE,QUANTITY FROM ORDERPRODUCTS ) OP ON OD.ORDERID=OP.ORDERID
INNER JOIN PRODUCTS P ON P.PRODUCTID=OP.PRODUCTID
INNER JOIN SUBCATEGORY SC ON SC.SUBCATEGORYID=P.SUBCATEGORYID
WHERE CONVERT(DATETIME,CONVERT(VARCHAR(50),OD.DELIVERYDATE,101)) BETWEEN #STARTDATE AND #ENDDATE
GROUP BY OP.PRODUCTID,OP.PRICE,SC.SUBCATEGORYNAME
---SECOND DURATION----
UNION ALL --ADDED NOW
SELECT DISTINCT OP.PRODUCTID AS ID,OP.PRICE AS PRC,SC.SUBCATEGORYNAME AS SCNAME,COUNT(OP.PRODUCTID) AS QTY, ROUND(SUM(OP.PRICE * OP.QUANTITY), 0) AS REVENUE
FROM ORDERDETAILS OD INNER JOIN
(SELECT DISTINCT ORDERID,PRODUCTID,PRODUCTFEATURES,PRICE,QUANTITY FROM ORDERPRODUCTS ) OP ON OD.ORDERID=OP.ORDERID
INNER JOIN PRODUCTS P ON P.PRODUCTID=OP.PRODUCTID
INNER JOIN SUBCATEGORY SC ON SC.SUBCATEGORYID=P.SUBCATEGORYID
WHERE CONVERT(DATETIME,CONVERT(VARCHAR(50),OD.DELIVERYDATE,101)) BETWEEN #STARTDATE1 AND #ENDDATE1
GROUP BY OP.PRODUCTID,OP.PRICE,SC.SUBCATEGORYNAME
)
AS A
)B
ORDER BY ID2, NAME
END
Based on your sample data i have given this Out put but if the data is inconsistent it may not give accurate results if you see the Expected Output it gives exact same
Declare #Table1 TABLE
(Id VARCHAR(10), Name varchar(5),Qty VARCHAR(10), Price varchar(10))
;
INSERT INTO #Table1
(Id, Name,Qty, Price)
VALUES
(1, 'Rose',4, 540),
(1, 'Rose',1, 640),
(2, 'Lilly',5, 550),
(2, 'Lilly',18, 360),
(3, 'Grand',2, 460),
(3, 'Grand',10, 360),
(4,'Lotus',0,0),
(4, 'Lotus',9, 580)
;
SCRIPT
;WITH CTE AS (
Select
CASE WHEN RN = 1 THEN ID ELSE NULL END ID,
CASE WHEN RN = 1 THEN Name ELSE NULL END NAME,
Qty,
Price
from (
select
Id,
Name,
Qty,
Price,
ROW_NUMBER()OVER(PARTITION BY ID,NAME ORDER BY NAME)RN
FROM
#Table1)T)
Select CASE WHEN RN = 2 THEN T.Id ELSE '' END ID,
CASE WHEN RN = 2 THEN T.Name ELSE '' END Name,
CASE WHEN RN IN (1,3) THEN ISNULL(T.Qty,0) ELSE '' END qty,
CASE WHEN RN IN (1,3) THEN ISNULL(T.Price,0) ELSE '' END qty from (
Select
T.ID,
T.NAME,
c.Qty,
C.Price,
ROW_NUMBER()OVER(PARTITION BY T.ID,T.NAME ORDER BY T.NAME)RN
from #Table1 T
INNER JOIN CTE C
ON T.Id = C.ID
AND T.Name = C.NAME
OR (T.Qty = C.Qty OR T.Price = C.Price ))T
WHERE T.RN <> 4

SQL Inner join not working to get change from previous date

I have a table with the following data :
TradeDate Stock BuySell DayClose
--------------------------------------
10-Dec-12 ABC 1 11
10-Dec-12 ABC 2 12
11-Dec-12 ABC 1 11.5
11-Dec-12 ABC 2 12.5
11-Dec-12 DEF 1 15
11-Dec-12 DEF 2 16
and I want to query on it for a particular date 11-Dec-2012 to get the following output :
Stock Buy Sell Mid Change
--------------------------------------
ABC 11.5 12.5 12.0 0.5
DEF 15 16 15.5
Since DEF does not have data for the previous date, change should be blank for it.
I have created the following query :
Select Stock,
AVG(CASE BuySell WHEN 1 THEN DayClose END) AS 'Buy',
AVG(CASE BuySell WHEN 2 THEN DayClose END) As 'Sell',
Sum(DayClose/2) as 'Mid',
Sum(Change/2) AS Change
FROM (
select t1.Stock, t1.BuySell, t1.DayClose, Sum(t1.DayClose - t2.DayClose) as Change
FROM #myTable as t1 inner join #myTable as t2 on
t1.Stock = t2.Stock
where
t1.TradeDate = '2012-12-11' AND
t2.TradeDate = (SELECT TOP 1 TradeDate FROM #myTable WHERE TradeDate < '2012-12-11' ORDER BY TradeDate DESC)
GROUP BY
t1.Stock, t1.buysell, t1.dayclose ) AS P1 GROUP BY stock
I created a temp table #mytable for this purpose :
drop table #mytable
CREATE TABLE #myTable
(
TradeDate datetime,
stock varchar(20),
buysell int,
dayclose decimal(10,2)
)
insert into #mytable values ('10-dec-2012', 'abc' , 1, 11)
insert into #mytable values ('10-dec-2012', 'abc' , 2, 12)
insert into #mytable values ('11-dec-2012', 'abc' , 1, 11.5)
insert into #mytable values ('11-dec-2012', 'abc' , 2, 12.5)
insert into #mytable values ('11-dec-2012', 'def' , 1, 15)
insert into #mytable values ('11-dec-2012', 'def' , 2, 16)
But I am not able to get the required output, rather getting
Stock Buy Sell Mid Change
--------------------------------------------------------------
abc 11.500000 12.500000 12.00000 1.00
Can someone tell me where am I going wrong. I seem to be lost in here.
Thanks,
Monika
Please try:
;WITH T1 as(
SELECT a.TradeDate
,a.stock
,SUM(CASE WHEN a.BuySell = 1 THEN a.DayClose ELSE 0 END) Buy
,SUM(CASE WHEN a.BuySell = 2 THEN a.DayClose ELSE 0 END) Sell
,SUM(a.DayClose) / 2 AS Mid
FROM #mytable a
GROUP BY a.TradeDate, a.stock
)SELECT t.*,
t.Mid - PR.Mid AS Change
FROM T1 t
LEFT JOIN
T1 PR ON
PR.TradeDate = DATEADD(DAY, -1, t.TradeDate)
AND PR.stock = t.stock
Try this:
SELECT a.TradeDate
,a.stock
,SUM(CASE WHEN a.BuySell = 1 THEN a.DayClose ELSE 0 END) Buy
,SUM(CASE WHEN a.BuySell = 2 THEN a.DayClose ELSE 0 END) Sell
,SUM(a.DayClose) / 2 AS Mid
INTO #temp
FROM #mytable a
GROUP BY a.TradeDate, a.stock
SELECT t.*,
t.Mid - previousRecord.Mid AS Change
FROM #temp t
LEFT JOIN
#temp previousRecord ON
previousRecord.TradeDate = DATEADD(DAY, -1, t.TradeDate)
AND previousRecord.stock = t.stock
DROP TABLE #temp
All you have to do now is to select the data for a date.
Select Stock,
AVG(CASE BuySell WHEN 1 THEN DayClose END) AS 'Buy',
AVG(CASE BuySell WHEN 2 THEN DayClose END) As 'Sell',
Sum(DayClose/2) as 'Mid',
Sum(Change/2) AS Change
FROM (
select t1.Stock, t1.BuySell, t1.DayClose, Sum( t1.DayClose - t2.DayClose ) as Change
FROM #myTable as t1 left join #myTable as t2 on t2.TradeDate = (SELECT TOP 1 TradeDate FROM #myTable WHERE TradeDate < t1.TradeDate ORDER BY TradeDate DESC)
and t1.Stock = t2.Stock and t1.buysell=t2.buysell
where
t1.TradeDate = '11-12-2012'

SQL Query in finding out the max number from a table with Null value

How Can I work out this requirement. Please help.
Client Table - CT
ClientID Balance
123 10
123 20
123 30
123 40
124 50
124 60
124 Null
I want to find our the max(Balance) from the CT Table.
Condition - > If there is no null value then I have to find out max(Balance) otherwise It should be Null. See below result, that am expecting.
ClientID Balance
123 40
124 Null
Am writing the query as below. But Is there any more dynamic way to do?
Select ClientID,
CASE WHEN MIN(Balance) = NULL THEN
NULL
ELSE
MAX(Balance) END AS 'MaxBalance'
From CT
Group by clientID
Please let me know, is there any otheralternative?
Try this:
Select ClientID,
(CASE WHEN count(balance) < count(*)
THEN NULL
ELSE MAX(Balance)
END) AS MaxBalance
From CT
Group by clientID
Or, a bit more cumbsersome, but perhaps clearer:
Select ClientID,
(CASE WHEN sum(case when balance is null then 1 else 0 end) > 0
THEN NULL
ELSE MAX(Balance)
END) AS MaxBalance
From CT
Group by clientID
How about:
SELECT clientid
, balance
FROM
(
SELECT clientid
, balance
, row_number()
over( partition by clientid
order by CASE WHEN balance IS NULL THEN 0 ELSE 1 END
, balance DESC
) r
FROM ct
) n
WHERE r = 1
I'm not sure what datatype [Balance] is, but if it is an int, you can do the following:
Select ClientID, NULLIF(MAX(ISNULL(Balance,2147483647)),2147483647)
From CT
GROUP BY ClientID
If [Balance] is not an int, just replace 2147483647 with the max value of that datatype.
The danger, of course, would be if you really do have a client with a balance of 2147483647. In such a case their max balance would show as null.
This will work on SQL 2005+
; WITH a AS (
SELECT DISTINCT ClientID
FROM CT
WHERE Balance IS NULL )
SELECT t.ClientID, MAX(t.Balance) "MaxBalance"
FROM CT t
LEFT JOIN a ON t.CLientID = a.ClientID
WHERE a.ClientID IS NULL
GROUP BY t.CLientID
UNION ALL
SELECT a.ClientID, NULL
FROM a
This works but is not very elegant:
SELECT SUB.ClientID, CASE (SELECT COUNT(ClientID)
FROM MyTable MT
WHERE Balance IS NULL
AND MT.ClientID = SUB.ClientID)
WHEN 0 THEN (SELECT MAX(Balance)
FROM MyTable MT
WHERE MT.ClientID = SUB.ClientID)
ELSE NULL END AS Balance
FROM (SELECT ClientID
FROM [MyTable]
GROUP BY ClientID) SUB