Trying to figure out how to use PIVOT in Sql Server - sql-server

I have a table named Work with two columns - Name and Status:
SELECT Name,Status FROM Work
--------+----------
Name |Status
--------+----------
MyBJE |2
MyBJE_2 |9
MyBJE |8
MyBJE_2 |9
MyBJE |7
MyBJE_2 |9
MyBJE |2
MyBJE |8
MyBJE_2 |3
MyBJE |8
MyBJE |8
MyBJE_2 |1
MyBJE_2 |8
MyBJE |4
I am trying to figure out how to write a query, which would return the following result from the aforementioned data:
--------+-------+-------+-------
Name |COUNT_2|COUNT_3|COUNT_4
--------+-------+-------+-------
MyBJE |2 |0 |1
MyBJE_2 |0 |1 |0
The expected semantics is as follows:
Ignore all the entries with the Status other than 2, 3 or 4
For each given Name count the occurrences of 2, 3 and 4 and display the total count in a dedicated column.
If a Name does not have any entry with the Status of 2, 3 or 4 make sure this Name does appear in the result with 0 in every COUNT_X column.
Here is what I did so far (the data is taken from a real database, not the example from above).
SELECT Name, Status, COUNT(1)
FROM (SELECT Name, (CASE when Status IN (2,3,4) then Status else 0 end) as Status FROM Work) x
GROUP BY Name, Status
--------+------+----------------
Name |Status|(No column name)
--------+------+----------------
MyBJE_2 |0 |262
MyBJE_2 |2 |1033
MyBJE |0 |2496
Now I know I am supposed to use the PIVOT statement, but I just can't figure out how.

Select name,
sum(case when status=2 then 1 else 0 end) as Count_2,
sum(case when status=3 then 1 else 0 end) as Count_3,
sum(case when status=4 then 1 else 0 end) as Count_4
from work
group by name

select Name,sum(Case when Status=2 then 1 Else 0 End) Count_2,sum(Case when Status=3 then 1 Else 0 End) Count_3,
sum(Case when Status=4 then 1 Else 0 End) Count_3
From tableName
where Status in(2,3,4)
Group By Name

Related

Converting Data to Tenths and averaging values

so I have a table in thousandths of a mile like this:
id |fk |from |to |speed|score
1 |123|10.002|10.003|20 |10
2 |123|10.003|10.004|25 |11
3 |123|10.004|10.005|40 |44
4 |123|10.005|10.006|50 |23
5 |123|10.006|10.007|20 |54
6 |123|10.007|10.008|10 |24
7 |123|10.008|10.009|65 |24
8 |123|10.009|10.010|23 |24
9 |123|10.010|10.011|74 |56
10 |123|10.011|10.012|25 |43
11 |123|10.012|10.013|10 |76
12 |123|10.013|10.014|5 |10
...
I need to convert the thousandth mile table to tenths of a mile and take average of speed and score like this:
id |fk |from |to |Avgspeed|Avgscore
1 |123|10.002|10.012|35.2 |31.3
10 |123|10.012|... |... |...
I came up with this query to get the tenth of a mile:
select CASE WHEN rn=1 then 1
when rn%10=0 then 1
else 0 end chk,x.* from
(
select row_number() over (partition by fk order by fk,from) rn,* from dbo.Thous_Data
)x
This gives me
id |fk |from |to |speed|score|chk|rn
1 |123|10.002|10.003|20 |10 |1 |1
2 |123|10.003|10.004|25 |11 |0 |2
3 |123|10.004|10.005|40 |44 |0 |3
4 |123|10.005|10.006|50 |23 |0 |4
5 |123|10.006|10.007|20 |54 |0 |5
6 |123|10.007|10.008|10 |24 |0 |6
7 |123|10.008|10.009|65 |24 |0 |7
8 |123|10.009|10.010|23 |24 |0 |8
9 |123|10.010|10.011|74 |56 |0 |9
10 |123|10.011|10.012|25 |43 |1 |10
11 |123|10.012|10.013|10 |76 |0 |11
12 |123|10.013|10.014|5 |10 |0 |12
...
Not sure how to proceed with getting the averages and setting up the from and to correctly. Any ideas appreciated.
Something like this?
SELECT 10 * FLOOR(id / 10) , AVG(speed), MIN( [from] ) , MAX( [to])
FROM dbo.Thous_Data
GROUP BY 10 * FLOOR(id / 10);
The way I was able to do it was by starting the count from 0 so that the brackets would be accurate:
with cte as
(select CASE WHEN rn=0 then 1
when rn%10=0 then 1
else 0 end chk,x.*
from
(
select ROW_NUMBER() over (partition by fk order by fk,from)-1 rn,* from dbo.Thous_Data
)x
)
,cte2 as(
SELECT
distinct fk,to,from,
SUM([Chk]) OVER (PARTITION BY fk ORDER BY to,from) AS Groups
FROM cte
)
Select distinct fk,
Min(from) over (partition by fk,groups) from_
,Max(to) over (partition by fk,groups) to_
,avg(speed) over (partition by fk,groups) Aspeed
,avg(score) over (partition by fk,groups) Ascore
from
cte2

How to get a unique count of decoded/unpivoted rows (column to row)

Working with Oracle DB.
Having an issue converting an set of columns to rows and getting a unique count for each row.
I'm working with a table that identifies a set of values (up to six) that are attached to a specific account number. I wanted to unpivot these six columns so that they are listed in there own row. Each row would have a count representing the positional value (i.e., Value 1 = 1, Value 3 = 3, etc...)
For example, I have a table like below.
The Values(1-6) will always be unique per Account Number
AccountNumber|Value1|Value2|Value3|Value4|Value5|Value6
-------------------------------------------------------
1 |123 |1234 |12345 |12 |12345 |1234
2 |123 |1234 |12345 |12 |12345 |1234
3 |123 |1234 |12345 |12 |12345 |1234
And I want the order of precedence to be attached to the Value number.
AccountNumber|Order|Value
-------------------------
1 |1 |123
1 |2 |1234
1 |3 |12345
1 |4 |12
1 |5 |123456
1 |6 |1
2 |1 |123
2 |2 |1234
2 |3 |12345
2 |4 |12
2 |5 |123456
2 |6 |1
3 |1 |123
3 |2 |1234
3 |3 |12345
3 |4 |12
3 |5 |123456
3 |6 |1
I have the following,
SELECT
'1' AS FACILITYID,
HL.ACCOUNT_ID AS AccountNumber,
--UNPIVOT_ROW,
DECODE(UNPIVOT_ROW, 1, TDL.DX_ONE_ID,
2, TDL.DX_TWO_ID,
3, TDL.DX_THREE_ID,
4, TDL.DX_FOUR_ID,
5, TDL.DX_FIVE_ID,
6, TDL.DX_SIX_ID) AS Value,
FROM ACCOUNT_LIST HL
INNER JOIN TRANSACTIONS TRAN ON HL.ACCOUNT_ID = TRAN.ACCOUNT_ID,
(SELECT LEVEL AS UNPIVOT_ROW FROM DUAL CONNECT BY LEVEL <= 6)
I am able to unpivot (using DECODE(), UNPIVOT() was giving me issues) but I can't seem to wrap my head around associating a unique count.
This is probably easy but it is just slipping out of my head trying to think of an efficient way to handle the 20,000+ plus rows before I unpivot without to much overhead.
I tried returning the value UNPIVOT_ROW and using a second decode to output a number but it just kept spitting out the number '1'
Any help or suggestions would be greatly appreciated!
I think you're over-complicating this, and just need a basic unpivot operation:
select account_id as "AccountNumber", position as "Order", value as "Value"
from (
select 1 as facility_id, hl.account_id, tdl.dx_one_id, tdl.dx_two_id,
tdl.dx_three_id, tdl.dx_four_id, tdl.dx_five_id, tdl.dx_six_id
from account_list hl
inner join transactions tdl on hl.account_id = tdl.account_id
)
unpivot (value for position in (dx_one_id as 1, dx_two_id as 2, dx_three_id as 3,
dx_four_id as 4, dx_five_id as 5, dx_six_id as 6))
Demo with starting data to match your first example:
-- CTEs for sample data
with account_list (account_id) as (
select 1 from dual
union all select 2 from dual
union all select 3 from dual
),
transactions (account_id, dx_one_id, dx_two_id, dx_three_id, dx_four_id, dx_five_id, dx_six_id) as (
select 1, 123, 1234, 12345, 12, 12345, 1234 from dual
union all select 2, 123, 1234, 12345, 12, 12345, 1234 from dual
union all select 3, 123, 1234, 12345, 12, 12345, 1234 from dual
)
-- actual query
select account_id as "AccountNumber", position as "Order", value as "Value"
from (
select 1 as facility_id, hl.account_id, tdl.dx_one_id, tdl.dx_two_id,
tdl.dx_three_id, tdl.dx_four_id, tdl.dx_five_id, tdl.dx_six_id
from account_list hl
inner join transactions tdl on hl.account_id = tdl.account_id
)
unpivot (value for position in (dx_one_id as 1, dx_two_id as 2, dx_three_id as 3,
dx_four_id as 4, dx_five_id as 5, dx_six_id as 6))
order by facility_id, account_id, position;
which gets
AccountNumber Order Value
------------- ---------- ----------
1 1 123
1 2 1234
1 3 12345
1 4 12
1 5 12345
1 6 1234
2 1 123
2 2 1234
2 3 12345
2 4 12
2 5 12345
2 6 1234
3 1 123
3 2 1234
3 3 12345
3 4 12
3 5 12345
3 6 1234
18 rows selected.

How to get latest salary of each associate in sql, table have month and year column also. each associate have minimum 4 to 5 records

Here is my query
Select distinct ASSOCIATE_ID,
Rate_Billed,
Currency,
RateMultiplier,
UOM,
MONTH,
YEAR= MAX(YEAR) over (partition by associate_id)
from asso_billinghrs
Below is the sample data.
|ASSOCIATE_ID |Rate_Billed | Currency| RateMultiplier| UOM |MONTH|YEAR|
|---------------|------------|----------|-----------------|-----|-----|----|
|1 |23.78 |USD |1 |B |11 |2013|
|1 |23.78 |USD |1 |B |2 |2014|
|1 |23.78 |USD |1 |B |3 |2014|
|2 |1 |INR |0.0146701 |C |1 |2017|
|2 |1 |INR |0.0147451 |C |1 |2017|
Below is the output
|ASSOCIATE_ID| Rate_Billed|Currency|RateMultiplier|UOM|MONTH|YEAR|
|------------|-------------|--------|--------------|---|-----|----|
|1 |23.78 |USD |1 |B |3 |2014|
|2 |1 |INR |0.0147451 |C |1 |2017|
Get latest salary of each associate in sql table having month and year column also. Each associate have minimum 4 to 5 records
Thanks
Try this :
WITH CTE AS(
Select distinct ASSOCIATE_ID,
Rate_Billed,
Currency,
RateMultiplier,
UOM,
MONTH,
YEAR,
ROW_NUMBER()over (partition by associate_id ORDER BY [YEAR],[MONTH] DESC) RN
from asso_billinghrs)
SELECT *
FROM CTE
WHERE RN=1
You may try using RANK() to get the following output.
select * from
(select *,RANK() over(partition by ASSOCIATE_ID order by tblyear desc,tblmonth desc,ratemultiplier desc)as r from asso_billinghrs)T
where r = 1
Output:
|ASSOCIATE_ID| Rate_Billed|Currency|RateMultiplier|UOM|MONTH|YEAR|
|------------|-------------|--------|--------------|---|-----|----|
|1 |23.78 |USD |1 |B |3 |2014|
|2 |1 |INR |0.0147451 |C |1 |2017|
FIDDLE

Sum up delivered companies for every customer(ID)

I'm back in action ;) This time I have a pretty heavy task (I think).
Here's what I got:
|customerID ||company |compdel |Street |Code |Date 1 |Date 2 |
+-------------------------------+--------------------------------------+
|1 ||Example1 |DELExam1|ABC Rd.1|4025 |01.01.2015 |01.08.2015 |
|1 ||Example1 |DELExam1|ABC Rd.1|4025 |13.04.2015 |01.12.2015 |
|1 ||Example1 |DELExam2|DEL St.1|0212 |13.03.2015 |09.07.2015 |
|1 ||Example1 |DELExam3|REF Wy.1|9875 |26.05.2015 |16.09.2015 |
|2 ||Example2 |DELExam4|REG St.1|6754 |21.02.2015 |16.05.2015 |
|2 ||Example2 |DELExam5|HIO Wy.1|9999 |01.03.2015 |06.08.2015 |
|2 ||Example2 |DELExam5|HIO Wy.1|9999 |01.01.2015 |06.02.2015 |
I want to show for every customerID every delivered company (compdel) summed in one line with the earliest date in Date 1 and the newest Date in Date 2. To make it easier to understand, I want this result:
|customerID ||company |compdel |Street |Code |Date 1 |Date 2 |
+-------------------------------+--------------------------------------+
|1 ||Example1 |DELExam1|ABC Rd.1|4025 |01.01.2015 |01.12.2015 |
|1 ||Example1 |DELExam2|DEL St.1|0212 |13.03.2015 |09.07.2015 |
|1 ||Example1 |DELExam3|REF Wy.1|9875 |26.05.2015 |16.09.2015 |
|2 ||Example2 |DELExam4|REG St.1|6754 |21.02.2015 |16.05.2015 |
|2 ||Example2 |DELExam5|HIO Wy.1|9999 |01.01.2015 |06.08.2015 |
I tried it already with this select-Statement but it won´t work: I know, that this can only be a part of the answer....
SELECT *
FROM
(SELECT
customerID, company, compdel, Street, Code, Date 1, Date 2,
ROW_NUMBER() OVER(PARTITION BY compdel ORDER BY customerID) rn
FROM
table 1) as Y
WHERE
rn = 1
Use GROUP BY with distinct values (customerId, company etc.) and MIN and MAX for dates
SELECT CustomerId
, Company
, CompDel
, Street
, Code
, MIN(Date1) As EarliestDate1
, MAX(Date2) AS NewestDate2
FROM YourTable
GROUP BY CustomerId, Company, CompDel, Street, Code

How to get the count of each distinct value in Multiple columns and get the result in separate columns?

I need the following table to be queried to get the result given below the table.
Table:
----------------------------------
| Name | Age | slot |
|-------|--------|---------------|
|A |20 | 1 |
|B |30 | 2 |
|C |30 | 1 |
|D |20 | 1 |
|E |40 | 2 |
|F |40 | 3 |
|G |50 | 3 |
----------------------------------
Result:
-------------------------------------------
|Age |Age_Count |Slot |Slot_Count|
-------------------------------------------
|20 | 2 |1 |3 |
-------------------------------------------
|30 | 2 |2 |2 |
-------------------------------------------
|40 | 2 |3 |2 |
-------------------------------------------
|50 | 1 |
-----------------------
While searching stackoverflow i found this question for single column question and there is [this link for multiple columns] (get the count of each distinct value in "Multiple" columns) question. The answers from the second link (for the multiple coulmn's distinct count) is displayed under a single column and my requirement is i guess quite different from the answers posted there.
Thanks in advance
Your request is kind of odd. Are you sure you want that?
If so, this may help:
SET #x:=0,#y:=0,#m:=0,#n:=0;
SELECT
DISTINCT age,age_count, slot,slot_count
FROM (
SELECT
age, age_count, slot, slot_count
FROM (
SELECT
#x:=#x + 1 AS aid, age, COUNT(*) age_count
FROM
slots
GROUP BY age
) a
LEFT JOIN (
SELECT
#y:=#y + 1 AS sid, slot, COUNT(*) slot_count
FROM
slots
GROUP BY slot
) s ON a.aid = s.sid
UNION
SELECT
age, age_count, slot, slot_count
FROM (
SELECT
#m:=#m + 1 AS aid, slot, COUNT(*) slot_count
FROM
slots
GROUP BY slot
) a
LEFT JOIN (
SELECT
#n:=#n + 1 AS sid, age, COUNT(*) age_count
FROM
slots
GROUP BY age
) s ON a.aid = s.sid
) a
If you know for sure that you have more unique ages than unique slots , or opposite, you can get ride of messy union.

Resources