I have a table with the following structure
uid sid eid Key value
1 1 1 F.Name Simon
2 1 1 L.Name Jones
3 1 1 C.Name AAPL
4 1 1 Address Infinite
5 2 1 F.Name Brad
6 2 1 L.Name Pitt
7 2 1 C.Name Holly
8 2 1 Address LA
I would like to convert the above table to below format
sid F.Name L.Name C.Name Address
1 Simon Jones AAPL Infinite
2 Brad Pitt Holly LA
Basically I need values of "Key" column to be column fields in new table. I have no other table. Even Linq to sql is ok and I can understand it.
In 2005 and later:
SELECT *
FROM (
SELECT sid, key, value
FROM mytable
) q
PIVOT (
MIN(value)
FOR
key IN ([F.Name], [L.Name], [C.Name], [Address])
) p
Related
I'm trying to modify a table by add a column that can flag down all the duplicate Runner_Name based on the Track_Num. I tried using:
SELECT [Track_Num],
ROW_NUMBER() OVER (PARTITION BY [Track_Num] ORDER BY [Runner_Name]) - 1 As Dup,
[Runner_Name]
FROM [runner]
but it doesn't work, it's just sequencing the Runner_Name
The table runner that looks like this:
Track_Num Runner_Name
1 John
1 John
1 Jack
2 Amy
2 Mary
2 John
3 Josh
3 Josh
3 Taylor
The desired table that I hope to get is:
Track_Num Runner_Name Dup
1 John 1
1 John 1
1 Jack NULL
2 Amy NULL
2 Mary NULL
2 John NULL
3 Josh 1
3 Josh 1
3 Taylor NULL
Why not have a fifth option to choose from?
SELECT *, dup=(select 1 from runner
where track_num=r.track_num and runner_name=r.runner_name
having count(*)>1)
FROM runner r
This approach works without any windowing functions or common table expressions,
See the demo here: https://rextester.com/WPLCLP17296
Here is a demo with null values - they are not flagged as duplicates: https://rextester.com/AND4821
Perhaps just wrap the window function in sign(nullif( ... ,1))
Example
Select *
,Dup = sign(NullIf(sum(1) over (partition by [Track_Num],[Runner_Name] ) ,1))
From [runner]
Returns
Track_Num Runner_Name Dup
1 Jack NULL
1 John 1
1 John 1
2 Amy NULL
2 John NULL
2 Mary NULL
3 Josh 1
3 Josh 1
3 Taylor NULL
If I undrestand your question correctly, then try this
select [Track_Num],
[Runner_Name],
Case when Count(1) > 1 then 1 else null end as Dup
from runner
group by [Track_num], [Runner_Name]
Use a Common Table Expression to identify the runners that have duplicates:
With cte_dups
As
(
Select
r.Track_Num
, r.Runner_Name
, Count(*) As Track_Runner_Count
From dbo.Runner As r
Group By
r.Track_Num
, r.Runner_Name
)
Select
r.Track_Num
, r.Runner_Name
, Iif(c.Track_Runner_Count > 1, 1, Null)
From dbo.Runner As r
Left Outer Join cte_dups As c
On c.Track_Num = r.Track_Num
And c.Runner_Name = r.Runner_Name
First group by Track_Num, Runner_Name to get the count of each combination and then join to the table:
select
r.Track_Num,
r.Runner_Name,
case
when g.counter > 1 then 1
else null
end Dup
from runner r inner join (
select Track_Num, Runner_Name, Count(*) counter
from runner
group by Track_Num, Runner_Name
) g on g.Track_Num = r.Track_Num and g.Runner_Name = r.Runner_Name
I have three tables:
Table 1 : Emplyee Details
E_Id Name Department
1 A Manager
2 B Manager
3 C Manager
4 D Engineer
5 E Engineer
6 F Engineer
Table 2 : Salary Details
Sl_Id Name Amount
1 Bsaic_Mng 30000
2 Basic_ENG 20000
Table 3 : Employee Salary
ES_Id E_Id Sl_Id
1 1 1
2 2 1
3 4 2
4 5 2
Here in Table3 field E_ID is a reference to Table1.E_Id
and SL_ID is a reference to Table2.SL_id.
So I wanto Result Which Employee Has Not Salary Define Like E_Id 3 AND 6
You can achieve it as below:
Employee whose salary is not defined in EmployeeSalary table
SELECT *
FROM Emplyee
WHERE E_Id NOT IN (
SELECT E_Id
FROM EmployeeSalary
)
JOIN is not required here
You can do it using a LEFT JOIN like following.
SELECT ED.* FROM
[Emplyee Details] ED
LEFT JOIN [Employee Salary] ES ON ES.E_ID=ED.E_Id
WHERE ES.E_ID IS NULL
I feel NOT EXISTS should be a better option to achieve this for this case.
SELECT * FROM
[Emplyee Details] ED
WHERE NOT EXISTS
(
SELECT 1 FROM [Employee Salary] ES WHERE ES.E_ID=ED.E_Id
)
Could somebody please help me create a view in SQL server to get a percentage in a new column. For example I have two tables as below.
Table 1---> Subject | Table 2---->Exam
|
SubjectID SubName | ExamID SubjectID Result (bool)
1 Science | 1 1 1
2 Maths | 2 1 1
3 English | 3 1 0
4 History | 4 2 0
5 Art | 5 2 1
6 Geography | 6 3 0
| 7 4 1
|
As you can see, many subjects do not have exams hence result will be null in a joined view. I want to show the pass percentage of a subject. For example, in result column, 1 = pass, 0 = Fail. I want the result to look like below showing null fields as well.
SubjectID SubName PassPercentage
1 Science 66.66
2 Maths 50
3 English 0
4 History 100
5 Art null
6 Geography null
Here:
SELECT
Subject.SubjectId,
Subject.SubName,
(AVG(CONVERT(decimal,Exam.Result))*100) AS PassPercentage
FROM Subject
LEFT JOIN Exam on Subject.SubjectId = Exam.SubjectId
GROUP BY Subject.SubjectId, Subject.SubName
You can round percentage result (2 or without decimals) and add % sign if you want.
Use this query:
Select *,
(Select Avg(Cast(Result as decimal)) From Exam Where SubjectID=S.SubjectID)*100 as PassPercentage
From Subject as S
Result is:
SubjectID SubName PassPercentage
----------- --------------- ---------------------------------------
1 Science 66.666600
2 Maths 50.000000
3 English 0.000000
4 History 100.000000
5 Art NULL
6 Geography NULL
(6 row(s) affected)
Subquery will be executed for each row of subject table.
do:
select s.SubjectID, s.SubName,
case COUNT(e.Result)
when 0 then null
else SUM(CAST(e.Result AS INT)) * 100 / (COUNT(s.SubjectID))
end PassPrec
from Subject s
left join Exam e on s.SubjectID = e.SubjectID
group by s.SubjectID, s.SubName
there case is to get the null. nulls don't get counted in "count" function.
you can use code like this
;with cte1 as (
select subjectid, sum(result) ResultCount
from exam group by subjectid
), cte2 as (
select e.subjectid, c.ResultCount, count(e.examid) TotalExams from cte1 c
left join exam e on e.subjectid = c.subjectid
group by e.subjectid, c.ResultCount
) select s.subname, convert(decimal(10,2), (c.ResultCount/convert(decimal(10,2),c.TotalExams)) *100) as Percentage from subject s left join cte2 c
on s.subjectid = c.subjectid
for example I have data as found in the table below
tabel order
-----------------------------------------
id_order no_order order_date
-----------------------------------------
1 0000001 12-01-2013
2 0000002 15-01-2013
-----------------------------------------
tabel item_order
--------------------------------------------------
id_item_order id_order order_name
--------------------------------------------------
1 2 Product 1
2 2 Product 2
3 2 Product 3
4 2 Product 4
--------------------------------------------------
then I want to display the data from database with join as below
--------------------------------------------------
id_item_order order_name no_order
--------------------------------------------------
1 Product 1 0000002 A
2 Product 2 0000002 B
3 Product 3 0000002 C
4 Product 4 0000002 D
--------------------------------------------------
how to display the character "A - n" located behind no_order according to the amount of data that relate item_order with id_order in table order?
please help me. thank you
SQL Fiddle for testing
select i.id_item_order, i.id_order,
o.no_order || chr(rownum + 64) as no_order
from item_order i
inner join "order" o on o.id_order = i.id_order;
I dont know about oracle But i tries this using SQL and it works well
select TIO.id_item_order,TIO.order_name,[TO].no_order + char(ROW_NUMBER()
OVER (order by id_item_order )+64) as no_order
from
TableItemOrder TIO inner join TableOrder [TO] on [TO].id_order=TIO.id_order
It worked for me
This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
A real recursion with CTE?
Given a hierarchical table that references itself, such as an Employee table that has the following columns:
Table Employee
Column Id INT NOT NULL
Column ParentId INT NOT NULL (references Id)
Column Name NVARCHAR(60) NOT NULL
The following query will give me all records rooted at a given EmployeeId:
DECLARE #EmployeeId INT = <%insert EmployeeId here%>;
WITH CDE AS
(
SELECT
*,
0 AS Level
FROM
collaboration.Employee AS E
WHERE
Id = #EmployeeId
UNION ALL
SELECT
E.*,
CDE.Level + 1 AS Level
FROM
collaboration.Employee AS E
INNER JOIN
CDE ON E.ParentId = CDE.Id AND E.Id <> 0
)
SELECT DISTINCT
CDE.*
FROM
CDE
ORDER BY
CDE.Level
What I would like is to be able to sort by "branch" and then "level", if that makes sense. So given the following table:
1 0 John Smith
2 1 John Doe
3 1 Jane Williams
4 2 Ian Bond
5 2 James Fleming
I would like the result to look like:
1 0 John Smith
2 1 John Doe
4 2 Ian Bond
5 2 James Fleming
3 1 Jane Williams
I would like a solution that does not involve building up strings to facilitate sorting. If a solution is not possible, I would like to know why.
;WITH CDE AS
(
SELECT
*,
0 AS Level,
convert(nvarchar(50),id) as EPath
FROM
collaboration.Employee AS E
WHERE
Id = #EmployeeId
UNION ALL
SELECT
E.*,
CDE.Level + 1 AS Level ,
convert(nvarchar(50),Epath+'/'+CONVERT(nvarchar(5),e.id))
FROM
collaboration.Employee AS E
INNER JOIN
CDE ON E.ParentId = CDE.Id AND E.Id <> 0
)
SELECT DISTINCT
CDE.*
FROM
CDE
ORDER BY
EPath
By the way, SQL Server 2008 has a HierarchyID data type for just this kind of thing.