How to do rows to column in SQL Server with count - sql

How do I simply switch Rows with Column in SQL with count? Is there any way to do?
Actually i want against each unique mobile no with count and product name side by side means if two mobile no in table then count = 2 and side of that two product1,product2 shows in output.
ie turn this result:
Srno Name| Mobile| Count | ProductName
1 xyz 1234 1 LNM
2 PQR 5678 1 VCD
3 xyz 1234 1 KLM
4 PQR 5678 1 NMG
into this:
Srno Name| Mobile| Count | ProductName1 | ProductName2
1 xyz 1234 2 LNM KLM
2 PQR 5678 2 VCD NMG

If you have a limited products then you use row_number() & do conditional aggregation :
select min(srno) as srno, name, Mobile, count(*) as cnt,
max(case when seq = 1 then ProductName end) as ProductName1,
max(case when seq = 2 then ProductName end) as ProductName2
from (select t.*,
row_number() over (partition by name, Mobile order by srno) as seq
from table t
) t
group by name, Mobile;

Try this:
SET #row_number = 0;
SELECT
(#row_number:=#row_number + 1) AS Srno,
T1.name,
T1.Mobile,
SUM(T1.xCount + T2.xCount) as cnt,
max(T1.ProductName) as Product1,
max(T2.ProductName) as Product2
FROM Table1 as T1
LEFT JOIN Table1 AS T2 ON T1.name = T2.name
AND T2.srno > T1.srno
GROUP BY T1.name, T1.Mobile
ORDER BY Srno

Related

Alasql - group by and take the maximum result

I have a table in the below format:
Vendor Id Weight
AAA 1 1234
AAA 1 121
AAA 2 5182
BBB 1 311
BBB 1 9132
BBB 2 108
I need to group by "Vendor" and "Id" and sum the "Weight". Whichever "Id" has the maximum "Weight" has to be assigned to the corresponding "Vendor". In the below example, Id "2" of Vendor "AAA" has a maximum weight of 5182 compared to the Id "1" whose weight is 1355 (1234+121). Hence Id "2" should be assigned to vendor "AAA". Similarly for Vendor "BBB", Id "1" has to be assigned as it has the maximum weight 9443 (311+9132) compared to Id "2" whose weight is "108".
Result has to be
Vendor Id
AAA 2
BBB 1
I am trying to implement this in "Alasql" which is the query language for Google Apps Script.
Any suggestions would be appreciated.
you can use window functions to do that:
select * from (
select Vendor,id,sum(weight) summWeight, row_number() over (order by sum(weight) desc) rn
from yourtable
group by Vendor,id
) tt
where rn = 1
then this is how you can do it:
select t.*
from (
select Vendor,max(summWeight) Maxweight from (
select Vendor,id,sum(weight) summWeight
from yourtable
group by Vendor,id
) tt
group by Vendor
) tt join (
select Vendor,id,sum(weight) summWeight
from yourtable
group by Vendor,id
) t
on t.vendor = tt.vendor
and summWeight = Maxweight

SQL Join on the same table

Table T
P_ID | Name | Status
1 ABC Ordered
1 ABC Processing
1 ABC Imported
2 PQR Ordered
2 PQR Failed
3 LMN Ordered
Expected Result
Table T
P_ID | Name | Status
2 PQR Ordered
2 PQR Failed
3 LMN Ordered
I am not getting the correct result with the following query. I want to find all the records that have status Ordered but do not have the status "Imported".
select c1.P_ID,c1.Name,c2.Status
from T c1, T c2
where c1.P_ID = c2.P_ID
c1.Status="Ordered" and c2.status != "Imported"
Using Oracle 11g database
select c1.P_ID, c1.Name, c1.Status
from T c1
where c1.Status = 'Ordered' and
NOT EXISTS (SELECT 1
FROM T c2
WHERE c1.P_ID = c2.P_ID and c2.status = 'Imported'
);
You can use the following code:
select c1.P_ID,c1.Name,c1.Status
from T c1
where exists (select 1
from T
where P_ID = c1.P_ID
and Status="Ordered"
and rownum = 1)
and not exists (select 1
from T
where P_ID = c1.P_ID
and Status="Imported"
and rownum = 1)

Combine multiple rows into single row

I have below table :- table1
ID Desc
1 ABC
2 DEF
3 GHI
3 JKL
4 MNO
4 PQR
4 STU
I want to show data as :-
ID Desc
1 ABC
2 DEF
3 GHI
JKL
4 MNO
PQR
STU
I tried to make it as :-
select distinct ID , Desc from table1
But its not working.
In Sql server its possible :
Select distinct ID , stuff((SELECT ','+Description FROM #a a WHERE
t.id=a.id for xml path('')),1,1,'') Description
from #a T
Output : Id Desc
1 ABC
2 DEF
3 GHI,JKL
4 MNO,PQR,STU
for what i know you can't, you have to modify the look of your table after the request (for example in html)
This needs to be handled in presentation layer but you can query as below:
Select Case when Row_Number() over(Partition by Id order by Id) = 1 then Id else Null end as Id,
[Desc] from #data
Below query will generate the desired result.
SELECT CASE WHEN (Rank() Over(ORDER BY id ASC)) = (Row_Number() Over (ORDER BY id ASC)) THEN id ELSE NULL END as ID, desc FROM table1

SQL. How to select multiple rows by using the MIN and GROUP BY

ID UserId Name Amount RewardId
----------------------------
1 1 James 10.00 1
2 1 James 10.00 2
3 1 James 10.00 3
4 2 Dave 20.00 1
5 2 Dave 20.00 3
6 3 Lim 15.00 2
I'm trying to insert to another table, and this is the result that i'm struggling with:
Tbl1ID RewardId
------------------
1 1
1 2
1 3
4 1
4 3
6 2
I'm trying to get the MIN(ID) of each person and select all the RewardId that belong to that person.
You could do a simple self join to get the minimum id value per userid/rewardid combination;
SELECT MIN(a.id) Tbl1ID, b.RewardId
FROM mytable a
JOIN mytable b
ON a.name = b.name
GROUP BY b.userid, b.rewardid
ORDER BY tbl1id, rewardid;
An SQLfiddle to test with.
If you are running SQL Server 2008+, you can simplify it by using Window Function.
INSERT INTO AnotherTable (Tbl1ID, RewardID)
SELECT MIN(ID) OVER (PARTITION BY Name),
RewardID
FROM SourceTable
SQLFiddle Demo
Try this
SELECT tbl1id,RewardID From
table1 S JOIN
(
SELECT MIN(ID) as tbl1id,Name FROM table1 GROUP BY Name
) T ON T.Name = S.Name
ORDER BY tbl1id
FIDDLE DEMO
Output:
Tbl1ID RewardId
----------------
1 1
1 2
1 3
4 1
4 3
6 2
If you want insert into new table then try this out
Insert into Newtable (tbl1id,RewardID)
SELECT tbl1id,RewardID from
table1 S JOIN
(
SELECT MIN(ID) as tbl1id,Name
FROM table1
GROUP BY Name
) T ON T.Name = S.Name
ORDER BY tbl1id;
FIDDLE DEMO

Within the same group find and exclude records that have the same parent ID for certain types

I have a table like following:
GroupID ParentID Type
1 ABC IND
1 ABC IND
1 CDE ORD
1 EFG STD
2 ZZZ IND
2 ZZZ IND
2 ZZZ IND
3 YYY COR
3 YYY COR
I need to exclude those records that are in the same group, having the same parent ID and the type is IND or COR. But I need to keep those groups that have different parent ID and the type is not IND or COR.
So the result I want to get would be the following:
GroupID ParentID Type
1 ABC IND
1 ABC IND
1 CDE ORD
1 EFG STD
Somehow I am thinking to use
Rank () over(partition by GroupID order by ParentID), but it won't give me the results that I want.
Any thoughts? PS: This table has 5 Million+ records. Looking for the effective way to deal with it.
Thanks
The following gives you a list of the groupIDs you want to exclude
SELECT GroupID
FROM
(
SELECT GroupID,
COUNT(DISTINCT ParentID) AS PCount, COUNT(DISTINCT TypeCode) as TCount,
MAX(TypeCode) AS tCode
FROM tablename
GROUP BY GroupID
) t
WHERE PCount = 1 AND TCount = 1
AND (tCode = 'IND' OR tCode = 'COR')
Now select everything else
SELECT *
FROM tableName
WHERE GroupID not in (
SELECT GroupID
FROM
(
SELECT GroupID,
COUNT(DISTINCT ParentID) AS PCount, COUNT(DISTINCT TypeCode) as TCount,
MAX(TypeCode) AS tCode
FROM tablename
GROUP BY GroupID
) t
WHERE PCount = 1 AND TCount = 1
AND (tCode = 'IND' OR tCode = 'COR')
)
Test with fiddle --> http://sqlfiddle.com/#!3/f1d4f/15/0
How is
1 ABC IND
in result set? here type is IND and you mentioned the result set should not have type IND or COR?