how to convert rows to columns in SQL Server 2008 - sql-server-2008

I have a Table
F1 F2
-----------------
name Happy
Company a
City Gurgaon
name Deepak
Company b
City Delhi
I need the output as -
name company city
-----------------------
Happy a Gurgaon
Deepak b Delhi
I am using the query
SELECT
CASE WHEN F1='name'
THEN F2 ELSE NULL END) AS name,
CASE WHEN F1='Company'
THEN F2 ELSE NULL END) AS Company,
CASE WHEN F1='City'
THEN F2 ELSE NULL END) AS city
FROM table1
but I am getting the output as :
name company city
-----------------------------
Happy
a
Gurgaon
Deepak
b
Delhi
Can someone help please? I do not want to use PIVOT. Can this be achieved using inner join

Create a table to insert the elements with identity field
CREATE TABLE #TEMP(ID INT IDENTITY(1,1), F1 VARCHAR(20), F2 VARCHAR(20))
INSERT INTO #TEMP
SELECT * FROM
(
SELECT 'name' F1, 'Happy' F2
UNION ALL
SELECT 'Company', 'a'
UNION ALL
SELECT 'City', 'Gurgaon'
UNION ALL
SELECT 'name', 'Deepak'
UNION ALL
SELECT 'Company', 'b'
UNION ALL
SELECT 'City', 'Delhi'
)TAB
Since you don't have an Id for each set, we need to generate separate Id after every 3 records
and pivot according to that Id.
SELECT name, Company,City
FROM
(
-- Generate seperate Id after every 3 records
SELECT F1,F2,CAST((ID/3.5)AS INT)+1 RNO
FROM #TEMP
)P
PIVOT(MIN(F2)
FOR F1 IN (name, Company,City)) AS PVTTable
RESULT

Related

Given a list, how to get the count from mysql table?

Given a string list, I want to get the count of each item from the table. However, I don't know how to get the count(0) of item which does not exist in the table.
for example, I have a table as follow.
id name score
------------------------
1 aaa 10
2 ccc 20
3 aaa 10
4 ddd 15
Given a list ["aaa", "bbb", "ccc"] , I hope a query can return me a result like
aaa 2
bbb 0
ccc 1
I tried "select name, count(*) from table where name in ("aaa", "bbb", "ccc") group by name;", but the result is without the count of "bbb". Can I do it in a single query?
Your values list must be a rowsource, not a criteria in WHERE.
SELECT criteria.name, COUNT(table.score)
FROM ( SELECT 'aaa' name UNION ALL
SELECT 'bbb' UNION ALL
SELECT 'ccc' ) criteria
LEFT JOIN table USING (name)
GROUP BY name
Though you got your appropriate answer I am sharing here another way of doing it using JSON_TABLE()
create table yourtable( id int, name varchar(10), score int);
insert into yourtable values(1, 'aaa', 10),
(2 ,'ccc', 20),
(3 ,'aaa', 10),
(4 ,'ddd', 15);
Query:
SELECT value name, count(name) name_count
FROM
JSON_TABLE(
'["aaa", "bbb", "ccc"]',
"$[*]"
COLUMNS(
Value varchar(50) PATH "$"
)
) data left join yourtable on value=name
group by value;
Output:
name
name_count
aaa
2
bbb
0
ccc
1
db<fiddle here

Reject database table items using condition in SQL database

This is my database
studentId
course
grade
1
CSE115
F
2
CSE115
C
3
CSE115
A
3
EEE111
B
2
EEE111
F
1
EEE111
B
I want to execute a query that will only return the 'studentId' who has not failed in any course(No 'F' with the studentId in the table). In my example table I have showed only two courses(CSE115,EEE111) but in my case it can be 30 courses and only those student will be selected who has passed in all the courses given to the table. If a student passed in 29 courses except 1 course he will not be selected.
For example in the given table the output will be,
Output:
studentId
course
grade
3
CSE115
A
3
EEE111
B
Can anyone help me building the query?
You can get all the studentIds that failed at least once with this query:
SELECT studentId FROM tablename WHERE grade = 'F'
Use it with NOT IN to get the rows that you want:
SELECT *
FROM tablename
WHERE studentId NOT IN (SELECT studentId FROM tablename WHERE grade = 'F')
Or with NOT EXISTS:
SELECT t.*
FROM tablename t
WHERE NOT EXISTS (SELECT 1 FROM tablename tt WHERE tt.studentId = t.studentId AND grade = 'F')

How to select only one data from duplicate data in mysql?

I have table bio
ID Name Country Address
1 Dan America A
2 Dan Japan B
3 Dan Canada C
4 Marcus China D
5 Kurtis Nepal E
6 Kurtis Mexico F
7 Jack Indonesia G
I need to select only one from the duplicate value of column "Name". I expect the result like this.
ID Name Country Address
1 Dan America A
4 Marcus China D
5 Kurtis Nepal E
7 Jack Indonesia G
I used this query
SET SESSION sql_mode = ( SELECT REPLACE ( ##sql_mode, 'ONLY_FULL_GROUP_BY', '' ) );
Select * from bio group by name;
Is there any other way without using SET SESSION sql_mode = ( SELECT REPLACE ( ##sql_mode, 'ONLY_FULL_GROUP_BY', '' ) ); since if i didn't use that, it return error.
I have tried answer with forpass answer but it run very slow. Here is the Explain query.
id select_type table type possible_keys rows filtered Extra
1 PRIMARY b ALL 1095012 100.00 Using where
2 DEPENDENT SUBQUERY t ALL PRIMARY,semua 1095012 3.33 Range checked for each record (index map: 0x3)
You can do it with NOT EXISTS:
SELECT b.*
FROM bio b
WHERE NOT EXISTS (
SELECT 1
FROM bio t
WHERE t.Name = b.Name AND t.ID < b.ID
)
It can be easily achieved in MySQL 8.0 using the ROW_NUMBER() OVER (PARTITION BY ) window function. But in 5.7 you have to emulate the same function with variables. Something like below.
SELECT ID, Name, Country, Address
FROM (
SELECT *, IF (#prev <> name, #rn: = 0, #rn),
#prev: = Name,
#rn: = #rn + 1 AS rn
FROM bio,
(SELECT #rn: = 0 ) rn,
(SELECT #prev: = '') prev
ORDER BY Address ASC
) t
WHERE rn = 1;
Alternatively you can use simple join to avoid mentioning the column names
SELECT b1.*
FROM bio b1
JOIN
(
SELECT Name, Min(ID) AS ID FROM bio
GROUP BY Name
) b2
ON b1.Name = b2.Name AND b1.ID = b2.ID;

Id Column having diffrent values in another column need show with specilal value

I have one Table Test in this table Id column, FuelId and FuelDesc columns are there.values are like below table,Based on first three columns i need to create out put table like below please help me to get.
ID FuelID FuelDesc
100 01 Elec
101 02 Gas
102 02 Gas
100 02 Gas
101 01 Elec
103 01 Elec
O/P:-
ID Pamenttype
100 Both
101 Both
102 Gas
103 Elec
You can use a CASE expression, with the help of COUNT and MAX functions:
SELECT
ID,
PaymentType = CASE WHEN COUNT(FuelId) > 1 THEN 'Both' ELSE MAX(FuelDESC) END
FROM test
GROUP BY ID
SELECT ID, CASE WHEN rowCount = 1 THEN FuelDesc ELSE 'Both' END AS Pamenttype
FROM
(SELECT ID, MAX(FuelDesc) AS FuelDesc, COUNT(*) AS rowCount
FROM mytable
GROUP BY ID)
You can define Both as having one record with FuelID = '01' and another with FuelID = '02'. Assuming {ID, FuelID} is unique in table Test:
with BothPaymentTypes as (
select t1.ID
from Test t1
join Test t2 on t1.ID = t2.ID
where t1.FuelID = '01'
and t2.FuelID = '02'
)
select ID, 'Both' as Pamenttype
from BothPaymentTypes
union all
select ID, FuelDesc
from Test
where ID not in (select ID from BothPaymentTypes)
[SQL Fiddle Demo]
Alternatively, you can avoid the self-join with a COUNT and HAVING clause - again assuming {ID, FuelID} is unique:
with BothPaymentTypes as (
select ID
from Test
group by ID
having count(*) = 2
)
select ID, 'Both' as Pamenttype
from BothPaymentTypes
union all
select ID, FuelDesc
from Test
where ID not in (select ID from BothPaymentTypes)
[SQL Fiddle Demo]
WITH fuelCount
AS
(
SELECT ID, COUNT(FuelID) AS fuelCount
FROM Test GROUP BY ID
)
SELECT fc.ID,
CASE
WHEN fc.fuelCount > 1 THEN 'BOTH'
ELSE (SELECT t.FuelDesc FROM Test t WHERE t.ID = fc.ID)
END AS Pamenttype
FROM fuelCount fc

Sql query to combine two column values of diff ProductCode and with same Productname

I have following table
ID PCode Pname
----------------------------------
1 A1 Book
2 A2 Oxford Dictionary
3 A3 Book
Expected output:
ID PCode Pname
---------------------------------------
1 A1 Book_A1
2 A2 Oxford Dictionary
3 A3 Book_A3
If Pname is same for different Pcode then result need to be Pname_Pcode like Book_A1 and Book_A3.
Please give the solution which will helpful for me.
Thanks
You can join the same table again with the condition to take only the records having duplicates. Then check this condition in a case
select t1.id, t1.pcode, case when t2.pname is not null
then t2.pname + '_' + t1.pcode
else t1.pname
end as pname
from your_table t1
left join
(
select pname
from your_table
group by pname
having count(*) > 1
) t2 on t1.pname = t2.pname