Split values into column SQL - sql

I have 4 types of values in one single column and looking to split those values in 4 different columns using SQL.
This is my table:
Name Car
---------------
John Tesla
John Renault
John Mercedes
John VW
And I would like have this result:
Name Car1 Car2 Car3 Car4
-----------------------------------------
John Tesla Renault Mercedes VW
Can anyone help?
Thanks

You can use PIVOT for this.
Your example almost exactly matches the Microsoft help page, comment if you need more help-
https://technet.microsoft.com/en-us/library/ms177410(v=sql.105).aspx

Right, I figured it out. I didn't realise that when you execute a SELECT function in SQL, you are actually creating a new column. I thought you just merged columns together.
So my code was simply:
SELECT
(CASE WHEN car = "Tesla" THEN name ELSE Null END) as Car_type_1
(CASE WHEN car = "Renault" THEN name ELSE Null END) as Car_type_2
(CASE WHEN car = "Mercedes" THEN name ELSE Null END) as Car_type_3
(CASE WHEN car = "VW" THEN name ELSE Null END) as Car_type_4
Should have learnt the basics of SQL! Hope this helps anybody else in my situation.

Related

How to filter logic in SQL where element is not present for one of the user

I have table, and I need to find out the person name who dont have Iphone?
Ex. query should give from the below table as Mike.
I am trying to built logic using group by on name and Items where Item not equal to Iphone or by using 2 table but unable to get the result, can anyone suggest ?
Name
Items
Simon
Iphone
Simon
Tablate
Simon
Watch
Simon
Laptop
Jim
Iphone
Jim
Tablate
Jim
Watch
Jim
Laptop
Mike
Tablate
Mike
Watch
Mike
Laptop
I have table, and I need to find out the person name who dont have Iphone?
Using your table, you can use aggregation:
select name
from t
group by name
having sum(case when item = 'Iphone' then 1 else 0 end) = 0;
The having clause counts the number of rows with iphones. The = 0 says there are none for the name.
I like gordons answer but this might be easier to understand:
select name
from table
where name not in
(select name
from table
where item like 'Iphone')
If you need only a single record for each name go for this at the end:
group by name

Counting prefixes in a joined table in SQL

I am trying to count how many makes of car a person owns. Car makes are only defined by a prefix in my Links table.
Table 1 (Person)
UniqueID Name
PER0001 Adrian
PER0002 Michael
Per0003 James
Table 2 (Links)
UniqueID LinkEnd1_ID LinkEnd2_ID
LIN0001 PER0001 FER02332
LIN0002 PER0001 FER02112
LIN0003 PER0001 POR12122
LIN0004 PER0002 FER12321
LIN0005 PER0003 MAS12382
LIN0006 PER0003 FER22982
LIN0006 PER0003 MAS12232
Output (option 1)
Name Car_Make Count
Adrian FER 2
Adrian POR 1
Michael FER 1
James MAS 2
James FER 1
Output (option 2 - preferred)
Name FER POR MAS
Adrian 1 2
Michael 1
James 1 2
The reason I am using a link table to count the number of car makes is because every car make has a different table I would need to join in.
I've tried
select count left(LinkEnd2_ID,3) which doesnt work, i've also tried group by which I cant seem to crack.
I guess what I want to be able to do is
select
count(left(LinkEnd2_ID,3)='FER'
,count(left(LinkEnd2_ID,3)='POR'
,count(left(LinkEnd2_ID,3)='MAS'
but thats a query in a select and I decipher how to code that properly.
Heres where I am starting from (or the base I keep going back to start afresh)-
SELECT
Person.Unique_ID
,Person.Name
,left(Link.LinkEnd2_ID,3) as Car_Make
FROM
Person
LEFT JOIN
Links as Link
on Person.Unique_ID = Link.LinkEnd1_ID
Any help you can offer would be appreciated.
Nearly there, you just need to add a group by, and change all the columns to aggregate functions.
Your option 1:
SELECT
max(Person.Name) as Person_Name
,left(Link.LinkEnd2_ID,3) as Car_Make
,count(*) as No_of_Car
FROM
Person
LEFT JOIN
Links as Link
on Person.Unique_ID = Link.LinkEnd1_ID
GROUP BY
Person.Unique_ID
For your option 2, you need to wrap your aggregate functions around case statements
you have to hardcode the 3 different car make, so if you have unknown number of them, it wouldn't work.
SELECT
max(Person.Name) as Person_Name
,sum(case when left(Link.LinkEnd2_ID,3) ='FER' then 1 else 0 end) as FER
,sum(case when left(Link.LinkEnd2_ID,3) ='POR' then 1 else 0 end) as POR
,sum(case when left(Link.LinkEnd2_ID,3) ='MAS' then 1 else 0 end) as MAS
FROM
Person
LEFT JOIN
Links as Link
on Person.Unique_ID = Link.LinkEnd1_ID
GROUP BY
Person.Unique_ID

SQL Combine null rows with non null

Due to the way a particular table is written I need to do something a little strange in SQL and I can't find a 'simple' way to do this
Table
Name Place Amount
Chris Scotland
Chris £1
Amy England
Amy £5
Output
Chris Scotland £1
Amy England £5
What I am trying to do is above, so the null rows are essentially ignored and 'grouped' up based on the Name
I have this working using For XML however it is incredibly slow, is there a smarter way to do this?
This is where MAX would work
select
Name
,Place = Max(Place)
,Amount = Max(Amount)
from
YourTable
group by
Name
Naturally, if you have more than one occurance of a place for a given name, you may get unexpected results.

select from table A when condition is met in table B

Not the best title hence why I was unable to find a solution that would fix mine, point me in the direction if you know of one.
Currently I have the below query,
SELECT PRODUCT_NAME
,LIVE
,LOCATION
FROM PRODUCT_TABLE
WHERE ORDER = 'ONLINE'
AND LIVE = '0' OR '1'
This essentially is a really simple query that pulls back a lot of data in which I've been using Excel to drill down to what I need however as I'm sure you can imagine a really tedious process so preferably prefer to do it straight with SQL as I know it can be done just my knowledge has completely disappeared after not using it in a while.
But essentially what I'm wanting to achieve is looking for all products online that are live at a location (0 means YES in the above query) and have matching product name at another location that isn't live (in this case not live = 1).
For example below is some data that is formatted in a similar sort of way.
LOCATION LIVE PRODUCT_NAME
BERLIN 0 CHAIR
LONDON 1 CHAIR
PARIS 0 LAMP
PARIS 0 SOFA
WARSAW 1 CHAIR
MADRID 0 CHAIR
MANCHESTER 1 SOFA
If someone could provide a solution or point me in the right direction that would be great, thanks!
You want something like this:
select pt.*
from product_table pt
where pt.live = '0' and
exists (select 1
from product_table pt2
where pt2.product_name = pt.product_name and
pt2.location <> pt.location and
pt2.live = '1'
);
SELECT DISTINCT
pt.PRODUCT_NAME
,pt.LIVE
,pt.LOCATION
FROM PRODUCT_TABLE pt
LEFT JOIN PRODUCT_TABE pt2
on pt.NAME = pt2.NAME
AND pt2.LIVE = 1
AND pt.LOCATION != pt2.LOCATION
WHERE pt.ORDER = 'ONLINE'
AND pt.LIVE = '0'
AND pt2.NAME IS NOT NULL

SQL Count unique rows where a column contains two different values

I have taken a good look around and not been able to find any questions that match mine. Maybe I am not using the right language when searching or whatever, but here goes.
I have an SQL table called Classes that looks something like this
Student_Name | Class
--------------------
Edgar | Chemistry
Allan | Chemistry
Burt | Chemistry
Edgar | Math
Sue | Math
Hamilton | Math
Edgar | English
Sue | English
Edgar | German
Ben | German
I want to count how many students are taking both Math and German.
Assuming the following in this example:
- Student names are unique
- One student can have many classes
Logically I would use a select statement to get a result set of students who are taking Math. Then I would go through each Student_Name from the result set and check them against the table to see how many are taking German.
In this case I would expect a return of 1 as only Edgar is taking both Math and German.
Here are some of the queries I have tried so far to no avail :-(
This one was after doing some research on DISTINCT:
SELECT COUNT(DISTINCT Student_Name) FROM Classes WHERE Class = 'Math' AND Class = 'German';
And this one was after finding out more about GROUP BY:
SELECT COUNT(*) FROM (
SELECT DISTINCT Student_Name FROM Classes
WHERE Class IN ( 'Math', 'German' )
GROUP BY Student_Name
);
Neither of these came out quite right any help would be highly appreciated.
SELECT COUNT(*) totalStudent
FROM
(
SELECT student_name
FROM Classes
WHERE class IN ('Math','German')
GROUP BY student_name
HAVING COUNT(*) = 2
) subAlias
SQLFiddle Demo
OUTPUT
╔══════════════╗
║ TOTALSTUDENT ║
╠══════════════╣
║ 1 ║
╚══════════════╝
Could also do the following:
select count(distinct a.Student_name)
from Classes a inner join Classes b on
a.Class = 'German' and
b.Class = 'Math' and
a.Student_Name = b.Student_name;
This solves the problem where the table contains duplicate rows (as pointed out by a commenter to another answer)