join multiple queries result in to seperate columns - sql-server

hello everyone i have 3 queries it gives when i used union All its give me 3 rows i want to convert 3 rows into columns how can i do that please help me
here is my query
( select count(*) As TotalCount from Detail_User
where userkey = 172 )
--union
( select count(*) As ICount1 from Detail_User
where Parent_Name = 'A' and userkey = 172 )
--union
( select count(*) As ICount2 from Detail_User
where Parent_Name = 'B' and userkey = 172 )
its give me some thing like this
TotalCount
2
3
5
i want something like this
TotalCount ICount1 ICount2
2 3 5

Don't do a UNION, use a CASE WHEN in your SELECT like this
select
count(*) As TotalCount,
SUM(CASE WHEN Parent_Name = 'A' THEN 1 ELSE 0 END) as ICount1 ,
SUM(CASE WHEN Parent_Name = 'B' THEN 1 ELSE 0 END) as ICount2
from Detail_User
where userkey = 172

Related

Summation of the Grand total

I have the below requirement
As can be figure out that for every Collector whenever the SubProduct is changing, we are performing it's "SubTotal".
Once the "SubTotal" is over, then we are performing the "Product Total" which is the summation of the "SubProducts" for that collector at the Product level (means until the Product is changed).
and finally, "Grand Total" of that Collector's Product
e.g.
Collector Amreet has 2 Products (NCB and NCT). For NCB he has 2 subProducts viz. Credit Card and Loan. His Product Total is computed at both NCB and NCT level and Grand Total for all the products.
Same is the case for the collector "Vijay"
I have written the below code which is very close to the requirement only thing is that, I'm not able to Add/append Collector Name at the Grand Total Level.
My attempt so far
declare #t table(Collector varchar(50),Product varchar(50),SubProduct varchar(50),Amount int)
Insert into #t
select 'Vijay','NCB','Credit Card',8000 union all
select 'Vijay','NCB','Credit Card',2000 union all
select 'Vijay','NCB','Credit Card',17000 union all
select 'Vijay','NCB','Credit Card',5000 union all
select 'Vijay','NCB','Loan',15000 union all
select 'Vijay','NCB','Loan',5000 union all
select 'Amreet','NCB','Credit Card',3000 union all
select 'Amreet','NCB','Credit Card',1000 union all
select 'Amreet','NCB','Loan',45000 union all
select 'Amreet','NCB','Loan',9000 union all
select 'Amreet','NCT','Loan',1000 union all
select 'Amreet','NCT','Loan',2000
Select
*
from
(select
case when grouping(Rn) = 1 then '' else Collector end as Collector,
case when grouping(Rn) = 1 then '' else Product end as Product,
case
when grouping(Collector) = 0 and grouping(Product) = 1 and grouping(SubProduct) = 1 and grouping(Rn) = 1 then 'Grand Total'
when grouping(Collector) = 0 and grouping(Product) = 0 and grouping(SubProduct) = 1 and grouping(Rn) = 1 then 'Total(Product Total)'
when grouping(Collector) = 0 and grouping(Product) = 0 and grouping(SubProduct) = 0 and grouping(Rn) = 1 then 'SubTotal(Sub Product Total)'
else SubProduct end as SubProduct,
sum(Amount) as Amount
from
(select
*,
Rn = row_number() over(partition by Collector,Product,SubProduct order by 1/0)
from #t) tData
group by
rollup(Collector,Product,SubProduct, Rn))x
where x.SubProduct is not null
Output
Please check this one. Here I've added in one things.
declare #t table(Collector varchar(50),Product varchar(50),SubProduct varchar(50),Amount int)
Insert into #t
select 'Vijay','NCB','Credit Card',8000 union all
select 'Vijay','NCB','Credit Card',2000 union all
select 'Vijay','NCB','Credit Card',17000 union all
select 'Vijay','NCB','Credit Card',5000 union all
select 'Vijay','NCB','Loan',15000 union all
select 'Vijay','NCB','Loan',5000 union all
select 'Amreet','NCB','Credit Card',3000 union all
select 'Amreet','NCB','Credit Card',1000 union all
select 'Amreet','NCB','Loan',45000 union all
select 'Amreet','NCB','Loan',9000 union all
select 'Amreet','NCT','Loan',1000 union all
select 'Amreet','NCT','Loan',2000
Select
*
from
(select
case when grouping(Rn) = 1 then '' else Collector end as Collector,
case when grouping(Rn) = 1 then '' else Product end as Product,
case
when grouping(Collector) = 0 and grouping(Product) = 1 and grouping(SubProduct) = 1 and grouping(Rn) = 1 then 'Grand Total (' + Collector + ')'
when grouping(Collector) = 0 and grouping(Product) = 0 and grouping(SubProduct) = 1 and grouping(Rn) = 1 then 'Total(Product Total)'
when grouping(Collector) = 0 and grouping(Product) = 0 and grouping(SubProduct) = 0 and grouping(Rn) = 1 then 'SubTotal(Sub Product Total)'
else SubProduct end as SubProduct,
sum(Amount) as Amount
from
(select
*,
Rn = row_number() over(partition by Collector,Product,SubProduct order by 1/0)
from #t) tData
group by
ROLLUP(Collector,Product,SubProduct, Rn))x
where x.SubProduct is not null;

How to make Row_number() based on condition?

I have list of sample data. Using this I need new column which having sequence number. But condition of this sequence number is if consecutively InRange column value 1 then only it generate sequence number.In between if InRange value 0 then again sequence number start from 1 and so on.
Below query which I have created but not return expected result.
CREATE TABLE #Result (ID INT,Value INT,InRange BIT)
INSERT INTO #Result
SELECT 1 ,211,0
UNION SELECT 2 ,205,1
UNION SELECT 3 ,214,0
UNION SELECT 4 ,202,1
UNION SELECT 5 ,204,1
UNION SELECT 6 ,203,1
UNION SELECT 7 ,209,0
UNION SELECT 8 ,216,0
UNION SELECT 9 ,205,1
UNION SELECT 10 ,224,0
Query:
SELECT *
,CASE WHEN InRange=1 THEN ROW_NUMBER()OVER(Order by Id asc) ELSE 0 END AS ExpectedColumn
FROM #Result
Expected result.
ID Value InRange ExpectedColumn
1 211 0 0
2 205 1 1
3 214 0 0
4 202 1 1
5 204 1 2
6 203 1 3
7 209 0 0
8 216 0 0
9 205 1 1
10 224 0 0
This is a gaps and islands problem, with the islands being each group of records to which you want to assign its own row number sequence. One straightforward way to handle this uses the difference in row numbers method:
WITH cte1 AS (
SELECT *, ROW_NUMBER() OVER (ORDER BY ID) rn1
FROM #Result
WHERE InRange = 1
),
cte2 AS (
SELECT t1.*,
ROW_NUMBER() OVER (ORDER BY t1.ID) - t2.rn1 AS diff
FROM #Result t1
LEFT JOIN cte1 t2
ON t1.ID = t2.ID
)
SELECT ID, Value, InRange,
CASE WHEN InRange <> 0
THEN ROW_NUMBER() OVER (PARTITION BY diff ORDER BY ID)
ELSE 0 END AS ExpectedColumn
FROM cte2
ORDER BY ID;
Demo
with grouped_data as (
select
*,
count(case when InRange = 0 then 1 else null end) over(order by ID rows between unbounded preceding and current row) as group_number
from #Result
)
select
ID,
Value,
InRange,
row_number() over(partition by group_number order by ID) - 1 as expected_column
from grouped_data
order by ID;

check all the values of a column

select all the departments having students with even roll number
Dept No Roll No Student Name
1 1 lee
1 2 scott
2 2 scott
2 4 smith
1 4 smith
This should result in DEpt no 2 as it has only students with roll number divisible by 2
Another(imo easy and lightweight) way is using NOT EXISTS and DISTINCT:
SELECT DISTINCT [Dept No]
FROM dbo.TableName t
WHERE NOT EXISTS
(
SELECT 1 FROM dbo.TableName t2
WHERE t.[Dept No] = t2.[Dept No]
AND t2.[Roll No] % 2 = 1
)
Demo
If there is no odd number all must be even.
You can use GROUP BY with HAVING like this.
Query
SELECT [Dept No]
FROM departments
GROUP BY [Dept No]
HAVING SUM(CASE WHEN [Roll No] % 2 = 0 THEN 1 ELSE 0 END) > 1
AND SUM(CASE WHEN [Roll No] % 2 = 1 THEN 1 ELSE 0 END) = 0
Explanation
The query returns the departments if there a rollno which is even using SUM(CASE WHEN [Roll No] % 2 = 0 THEN 1 ELSE 0 END) > 1. If there is any rollno with odd roll no, SUM(CASE WHEN [Roll No] % 2 = 1 THEN 1 ELSE 0 END) will return non zero sum and that department will be excluded.
declare #t table (Dept int,Rno int,Student varchar(10))
insert into #t (Dept,Rno,Student)values (1,1,'lee'),(1,2,'scott'),(2,2,'scott'),(2,4,'smith'),(1,4,'smith')
SELECT Dept,Rno,Student
FROM (SELECT ROW_NUMBER () OVER (ORDER BY Rno DESC) row_number, Dept,Rno,Student
FROM #t) a WHERE (row_number%2) = 0

Select distinct rows where all values in a column are the same SQL Server

I want to find Distinct FKIDs where IsProcessed is True for the same FKIDs.
e.g.
CID FKID DataField IsProcessed
1 1 Test 1
2 1 Test 1
3 2 Test 0
4 2 Test 1
5 3 Test 0
6 3 Test 0
7 4 Test 1
8 5 Test 0
9 6 Test 1
10 6 Test 1
11 6 Test 1
I would like to get the following FKIDs Returned 1,4,6
because these are FKIDs where isprocessed is true for all instances.
Any help would be greatly appreciated! Thanks!
You could use SUM() OVER and COUNT() OVER
;WITH CTE AS(
SELECT
*,
IsProcessedCount = SUM(CASE WHEN IsProcessed = 1 THEN 1 ELSE 0 END) OVER(PARTITION BY FKID),
cc = COUNT(*) OVER(PARTITION BY FKID)
FROM TEST
)
SELECT
DISTINCT FKID
FROM CTE
WHERE IsProcessedCount = cc
Using GROUP BY and HAVING:
SELECT FKID
FROM Test
GROUP BY FKID
HAVING COUNT(FKID) = COUNT(CASE WHEN IsProcessed = 1 THEN 1 ELSE NULL END)
Another way:
SELECT FKID
FROM Test
GROUP BY FKID
HAVING COUNT(FKID) = SUM(CAST(IsProcessed AS INT))
Just replace TEST with your table.
Another way, using a correlated not exists predicate:
select fkid from TableName t
where IsProcessed = 1
and not exists
(select 1 from TableName where IsProcessed = 0 and FKID = t.FKID)
group by fkid
or the same using not in:
select fkid from TableName t
where IsProcessed = 1
and fkid not in
(select fkid from TableName where IsProcessed = 0 and FKID = t.FKID)
group by fkid
SELECT FKID
FROM TableName
GROUP BY FKID
HAVING (MIN(IsProcessed) = 1)
Or
SELECT FKID
FROM TableName
GROUP BY FKID
HAVING (MIN(CAST(IsProcessed AS INT)) = 1)
If IsProcessed is not of numeric type:

Count of rows for 2 days

My data is in below format:
employee order id date
a 123 01/06/2013
b 124 02/06/2013
a 125 02/06/2013
a 129 02/06/2013
I need the data in below format:
employee day 1 day 2
a 1 2
b 0 1
Try this one -
DECLARE #temp TABLE
(
dtStart DATETIME
, employees CHAR(1)
)
INSERT INTO #temp (employees, dtStart) VALUES('a','01/06/2013')
INSERT INTO #temp (employees, dtStart) VALUES('a','01/06/2013')
INSERT INTO #temp (employees, dtStart) VALUES('b','02/06/2013')
SELECT
employees
, day1 = COUNT(CASE WHEN DAY(dtStart) = 1 THEN 1 END)
, day2 = COUNT(CASE WHEN DAY(dtStart) = 2 THEN 1 END)
FROM #temp
--WHERE dtStart BETWEEN '01/06/2013' AND '30/06/2013'
GROUP BY employees
Something along these lines should work (depending on whether you have a fixed amount of days or not):
select employee,
SUM(CASE WHEN date = '01/06/2013' THEN 1 ELSE 0 END) as day1,
SUM(CASE WHEN date = '02/06/2013' THEN 1 ELSE 0 END) as day2
from table
group by employee
select distinct employees,
SUM(CASE WHEN dtStart = '01/06/2013' THEN 1 ELSE 0 END) as day1,
SUM(CASE WHEN dtStart = '02/06/2013' THEN 1 ELSE 0 END) as day2
from yourTable
group by dtStart,employees
see your demo

Resources