Here is what my initial dataset looks like
prof_id id title
1 5 A
1 5 B
1 5 C
1 5 D
2 5 C
2 5 D
2 5 E
NA 5 F
NA 5 G
Here is what the new table should look like:
prof_id id title
1 5 A
1 5 B
1 5 C
1 5 D
1 5 F
1 5 G
2 5 C
2 5 D
2 5 E
2 5 F
2 5 G
Any row with a null value for a prof_id should be attributed to all of the prof_id. I have provided an example where there are two '
prof_id but there are also instances where there are 1 or 0 prof_id.
For 1, all of the null should be attributed to that single prof_id
For 0, leave it as is
I'm new to SQL so I'm not sure how to start. Any guidance would be much appreciated.
Thanks
In this case, you will need to do cross join, where essentially it is going to multiply 2 tables together.
First to pick out all nulls:
select id, title from table where prof_id is null
Then pick out the prof_id you want to apply to all tables
select distinct prof_id from table where prof_is is not null
Do a cross join together, then union the rest of "good" data back
(select distinct prof_id from table where prof_is is not null)
CROSS JOIN
(select id, title from table where prof_id is null)
UNION ALL
(select prof_id, id, title from table where prof_id is not null)
You can generate all the rows using a cross join. Then use union all to combine this with the rest of the data.
The following syntax should work:
select p.prof_id, i.id, t.title
from (select distinct prof_id
from t
where prof_id <> 'NA' -- or do you mean is not null
) p cross join
(select distinct id from t) i cross join
(select distinct title
from t
where prof_id = 'NA' -- or is null
) t
union all
select prof_id, id, title
from t
where prof_id <> 'NA' -- or is not null
Related
I have a table variable that looks like this:
id
V1
V2
1
A
1
1
A
2
1
B
3
2
C
2
2
A
3
3
A
1
3
A
2
3
B
2
4
C
3
5
A
2
I would like to select only the ids where at least one V2 = 3, to get something like this:
id
V1
V2
1
A
1
1
A
2
1
B
3
2
C
2
2
A
3
4
C
3
What is the SQL query to do this?
Select *
From yourtable
where id in (
select distinct id
from yourtable
where v2 = 3
)
Try:
select v.* from variable01 v where id in (select distinct id from variable01 where V2=3 ) ;
Working demo : http://sqlfiddle.com/#!9/dd7175/1
For this type of problem, I usually recommend exists because it optimizes better across more databases (with the right indexing):
select v.*
from variable v
where exists (select 1
from variable v2
where v2.id = v.id and
v2.v2 = 3
);
You can also express this quite well using in. But importantly, select distinct is not needed in the subquery:
select v.*
from variable v
where v.id in (select v2.id
from variable v2
where v2.v2 = 3
);
I have these 3 tables
Table 1:
id_Table1 field_table1_1 field_table1_2
1 A B
2 C D
3 E F
Table 1:
id_Table2 field_table2_1 field_table2_2
4 G H
5 I J
List item
Table 3:
id_Table3 id_Table1 id_Table2
1 1 4
2 1 5
3 2 5
So table 3 holds the relation between table 1 and 2.
What I want to do, is with a query, get all the fields in the table 1, plus one extra field that contains all the ids of the table 2 separated by coma.
So the result should be something like this:
id_Table1 field_table1_1 field_table1_2 id_Table2
1 A B 4, 5
2 C D 5
3 E F
One option use a lateral join and string_agg():
select t1.*, x.*
from table1 t1
outer apply (
select string_agg(t3.id_table2) id_table2
from table3 t3
where t3.id_table1 = t1.id_table1
) x
There is no need to bring table2 to get the results you want.
Please help me to create query. I have table with languages like
Id Code
---------
1 EN
2 DE
3 RU
and table with translations
Id Code LanguageId Value
------------------------------------------
1 1 1 EnglishTranslation
2 1 3 RussianTranslation
3 2 1 EnglishTranslation
4 2 2 DeutschTranslation
5 3 1 EnglishTranslation
I'm trying to get this result
Id Code LanguageId Value
------------------------------------------
1 1 1 EnglishTranslation
1 1 2 NULL
2 1 3 RussianTranslation
3 2 1 EnglishTranslation
4 2 2 DeutschTranslation
4 2 3 NULL
5 3 1 EnglishTranslation
5 3 2 NULL
5 3 3 NULL
Need to get translations for all languages by Code from Translations table So far I try
select
T.id, T.Code, L.Id, T.Value
from Languages L
left join Translations T on T.LanguageId = L.Id
but I got not expected result. Could you please suggest
http://sqlfiddle.com/#!6/e9bed/1
You can use CROSS JOIN operator to construct a cartesian product of (LanguageId, Code) pairs, and left-join translation table to it:
SELECT
t.Id, y.Code, x.LanguageId, t.Value
FROM
((SELECT Id AS LanguageId FROM Languages) AS x
CROSS JOIN
(SELECT DISTINCT(Code) AS Code FROM Translations) AS y)
LEFT OUTER JOIN Translations t ON y.Code=t.Code AND x.LanguageId=t.LanguageId
ORDER BY t.Code, t.LanguageId
Note that this wouldn't produce a valid translation Id for rows missing from Translations, i.e. the result would look like this:
Id Code LanguageId Value
---------------------------------------------
1 1 1 EnglishTranslation
NULL 1 2 NULL
2 1 3 RussianTranslation
3 2 1 EnglishTranslation
4 2 2 DeutschTranslation
NULL 2 3 NULL
5 3 1 EnglishTranslation
NULL 3 2 NULL
NULL 3 3 NULL
Demo.
I resolved the issue and got the result that you expected.
Run the below query:
SELECT
(CASE
WHEN T.Id is null and lc.Code = 1 THEN 1
WHEN T.Id is null and lc.Code = 2 THEN 4
WHEN T.Id is null and lc.Code = 3 THEN 5
ELSE T.Id
END) as Id,
lc.Code, lc.Id as LanguageId, T.Value from
(SELECT x.Id, y.Code from (SELECT Id FROM Languages) x cross join (SELECT DISTINCT(Code) as Code FROM Translations) y) as lc
left outer join Translations T ON lc.Id = T.LanguageId and lc.Code = T.Code
order by Id, Code, LanguageId
You can also see the solution in the below link:
http://sqlfiddle.com/#!6/e9bed/30
Hopefully it will work as you like.
Have a table like that. Let's pretend it is full table and we dont have any other rows:
ID Place
1 A
1 B
2 C
3 D
How can I perform such thing:
ID Place YesNo
1 A 1
1 B 1
1 C 0
1 D 0
2 A 0
2 B 0
2 C 1
2 D 0
3 A 0
3 B 0
3 C 0
3 D 1
For yes/no I need CASE statement but how to do the rest- full join table on itlself or some other options?
Thanks!
You can achieve that with two subqueries which each list the possible values of one of the columns. The two results should then be crossed to get all combinations. Finally outer join this with the original table to see which combinations actually occur:
SELECT first.ID,
second.Place,
CASE WHEN mytable.ID IS NULL THEN 0 ELSE 1 END AS YesNo
FROM (
SELECT DISTINCT ID
FROM mytable
) first
CROSS JOIN (
SELECT DISTINCT Place
FROM mytable
) second
LEFT JOIN mytable
ON mytable.ID = first.ID
AND mytable.Place = second.Place
ORDER BY first.ID,
second.Place
Here is an SQL fiddle
I have this table:
id type otherid
1 4 1234
2 5 1234
3 4 4321
As you can see there are 3 records, 2 of them belongs to otherid "1234" and got type of 4 and 5.
Last record belongs to otherid of "4321" and has only a type of 4.
I need to select all otherid that got only the type 4 and not the type5.
Example: after this select on that table the query shuould return only the record 3
Thanks
add1:
Please consider the TYPE can be any number from 1 up to 20.
I only need otherid that got type 4 but not type 5 ( except than that they can have any other type )
add2:
using mysql 5.1
This is kind of a workaround
SELECT * FROM (
SELECT GROUP_CONCAT('|',type,'|') type,other_id FROM table GROUP BY otherid
) t WHERE type LIKE '%|4|%' AND type NOT LIKE '%|5|%'
You could use a not exists subquery:
select distinct otherid
from YourTable as yt1
where yt1.type = 4
and not exists
(
select *
from YourTable as yt2
where yt1.otherid = yt2.otherid
and yt1.type <> yt2.type -- use this line for any difference
and yt2.type = 5 -- or this line to just exclude 5
)
Another way is by using a left join from where you exclude rows that have both type 4 and 5:
select a.*
from table1 a
left join table1 b on b.otherid = a.otherid and b.type = 5
where a.type = 4 and b.id is null