union result of multiple dynamic queries sql - sql

I have two tables tblJobs and tblJobseeker.
tblJobs
JobId skill location
5 .net, php Mexico
8 java Boston
9 sql, c++ London, Mexico
tblJobseeker
ID skill location
3 .net Mexico
7 sql Boston
10 java Boston
12 php Mexico
13 c++ London, Boston
Now I want to loop through first table tblJobs and find matching Jobseeker based on skill and location. For each record in tblJobs a result will come which I need to union with other records result set. I was trying to use cursor and dynamic query but how I can set condition of column skill and location in dynamic query. Also the records in both tables may vary
In above case, result should be
ID skill location
3 .net Mexico
12 php Mexico
10 java Boston
13 c++ London, Boston
I have edited the question. Here I am using charindex to match the result and inner join is not possible.There can be n number of locations or skills so different columns are not possible.

Simple inner join would do:
select s.*
from tblJobseeker s
inner join tblJobs j
on s.skill = j.skill
and s.location = j.location;

Related

PostgreSQL dynamic query comparing row from table to column name of another table

I work with QGIS and PostgreSQL with PostGIS. I need help with dynamic queries for PostgreSQL.
Information is structured in tables that contain votes for parties, and other types of information like geographic area or election date.
I need to work with “tidy” data in plotly for pie charts. The desired end table must have one row per observation.
So for example for the given table “Election Results”:
Country
PartyA
PartyB
PartyC
Argentina
100
10
20
Uruguay
3
5
1
Chile
40
200
50
Values for columns to be treated like parties, are stored in table “Parties”:
Party
PartyA
PartyB
PartyC
PartyD
PartyE
I need to separate one observation of voting results per row as follows (“Ending Table”):
Country
Party
Votes
Argentina
PartyA
100
Argentina
PartyB
10
Argentina
PartyC
20
Uruguay
PartyA
3
Uruguay
PartyB
5
Uruguay
PartyC
1
Chile
PartyA
40
Chile
PartyB
200
Chile
PartyC
50
The query should work with any number of parties stored in the “Parties” table. The “parties” table could include some rows not present in the election results table, but all parties in the election results table will exist in the “parties” table.
I understand it should be done iterating over the columns in the “Election results” table. If the name of a column matches the value of a row in “party table”, then we “untidy” data as in the “ending table”.
You can "iterate" over the columns using Postgres's JSON functions:
Something like this:
select er."Country",
pv.*
from election_results er
cross join jsonb_each_text(to_jsonb(er) - 'Country') as pv(party, votes)
join parties p on p.party = pv.party
;
Online example

Relational Algebra count something as rename

How can I count the number of somethings in each column, and rename as something?
For example - this is my table:
PATIENT
PatientNum City
---------------------------
1 New York City
2 Boston
3 Birmingham
4 Tyler
5 Boston
6 New York City
This is my SQL query:
SELECT
City, COUNT(DISTINCT PatientNum) AS Freq
FROM
PATIENT
GROUP BY
City
Expected result
City Freq
----------------------
Birmingham 1
Boston 2
New York City 2
Tyler 1
What is the relational algebra for this SQL query?
I am new to relational algebra, thank you for help!
Update:
I have do some research and write that. Is that right?
You need to use the group by operator, γ. The columns listed before the γ are the grouping columns, the columns listed after are your projections
So, your expression in relational algebra would be like this:
City γ City, COUNT PatientNum (PATIENT)
Relational projections always return distinct tuples.

SQL (COUNT(*) / locations.area)

We are learning SQL at school, and my professor has this sql code in his documents.
SELECT wp.city, (COUNT(*) / locations.area) AS population_density
FROM world_poulation AS wp
INNER JOIN location
ON wp.city = locations.city
WHERE locations.state = “Hessen”
GROUP BY wp.city, locations.area
Everything is almost clear for me, just the aggregate function with /locations.area doesn't make any sense to me. Can anybody help?
Thank you in advance!
Look at what the query is grouped on, that tells you what each group consists of. In this case, each group is a city, and contains all the rows that have the same value for wp.city (and as the location table is joined on that value too, the locations.area is only included in the grouping so that it can be used in the result).
So each group has a number of rows, and the COUNT(*) aggregate will contain the number of rows for each group. The value of (COUNT(*) / locations.area) will be the number of rows in the group divided by the value of locations.area for that group.
If you would have data like this:
world_population
name city
--------- ---------
John London
Peter London
Sarah London
Malcolm London
Ian Cardiff
Johanna Stockholm
Sven Stockholm
Egil Stockholm
locations
city state area
----------- -------------- ---------
London Hessen 2
Cardiff Somehere else 14
Stockholm Hessen 1
Then you would get a result with two groups (as Cardiff is not in the state Hessen). One group has four people from London which has the area 2, so the population density would be 2. The other group has three people from Stockholm which has the area 1, so the population density would be 3.
Side note: There is a typo in the query, as it joins in the table location but refers to it as locations everywhere else.
Try writing it like:
SELECT wp.city,
locations.area,
COUNT(*) AS population,
(COUNT(*) / locations.area) AS population_density
FROM world_poulation AS wp
INNER JOIN location
ON wp.city = locations.city
WHERE locations.state = “Hessen”
GROUP BY wp.city, locations.area
The key is the GROUP BY statement. You are showing pairs of cities and areas. The COUNT(*) is the number of times a given pair shows up in the table you created by joining world population and location. The area is just a number, so you can divide the area by the COUNT.

Add columns to SQL query output

I have searched this site and others, and I am unable to find a clear answer, so here I am. In the below query, I will get an output with a single column for the county. What I would like to do can only be described in Excel parlance as transpose the counties so each county for a brand family is in its own column. I have played around with using pivot, but unfortunately do not fully grasp what would be required. This is not my first query, but I am relatively new to SQL scripting, so please ask any clarification questions and I will do my best to answer.
Some of the brand families have 10 counties and some have 20, so some of the columns would be blank. This is for an in-house DB, not the SO DB, running on SQL Server 2008R2, FWIW.
The script is:
select distinct b.reckey as BrandFamilyKey, b.recname as BrandFamilyName,
g.recname as County
from territories as t
left join dbo.TerritoryBrandFamilies as tbf on tbf.TerritoryNid = t.TerritoryNid
left join Customers as c on c.TerritoryNid = t.TerritoryNid
left join GeographicAreas as g on g.GeoAreaNid = c.GeoAreaNid
left join brandfamilies as b on b.brandfamilynid = tbf.brandfamilynid
where t.activeflag = 1 AND C.GeoAreaNid IS NOT NULL and b.activeflag = 1
order by b.RecName,g.recname
the output would look like
brand family 1 county 1
brand family 1 county 2
brand family 1 county 3
What I would like to see is:
brand family 1 county 1 county 2 county 3

Multiple JOIN (SQL)

My problem is Play! Framework / JPA specific. But I think it's applicable to general SQL syntax.
Here is a sample query with a simple JOIN:
return Post.find(
"select distinct p from Post p join p.tags as t where t.name = ?", tag
).fetch();
It's simple and works well.
My question is: What if I want to JOIN on more values in the same table?
Example (Doesn't work. It's a pseudo-syntax I created):
return Post.find(
"select distinct p from Post p join p.tags1 as t, p.tags2 as u, p.tags3 as v where t.name = ?, u.name = ?, v.name = ?", tag1, tag2, tag3,
).fetch();
Your programming logic seems okay, but the SQL statement needs some work. Seems you're new to SQL, and as you pointed out, you don't seem to understand what a JOIN is.
You're trying to select data from 4 tables named POST, TAG1, TAG2, and TAG3.
I don't know what's in these tables, and it's hard to give sample SQL statements without that information. So, I'm going to make something up, just for the purposes of discussion. Let's say that table POST has 6 columns, and there's 8 rows of data in it.
P Fname Lname Country Color Headgear
- ----- ----- ------- ----- --------
1 Alex Andrews 1 1 0
2 Bob Barker 2 3 0
3 Chuck Conners 1 5 0
4 Don Duck 3 6 1
5 Ed Edwards 2 4 2
6 Frank Farkle 4 2 1
7 Geoff Good 1 1 0
8 Hank Howard 1 3 0
We'll say that TAG1, TAG2, and TAG3 are lookup tables, with only 2 columns each. Table TAG1 has 4 country codes:
C Name
- -------
1 USA
2 France
3 Germany
4 Spain
Table TAG2 has 6 Color codes:
C Name
- ------
1 Red
2 Orange
3 Yellow
4 Green
5 Blue
6 Violet
Table TAG3 has 4 Headgear codes:
C Name
- -------
0 None
1 Glasses
2 Hat
3 Monacle
Now, when you select data from these 4 tables, for P=6, you're trying to get something like this:
Fname Lname Country Color Headgear
----- ------ ------- ------ -------
Frank Farkle Spain Orange None
First thing, let's look at your WHERE clause:
where t.name = ?, u.name = ?, v.name = ?
Sorry, but using commas like this is a syntax error. Normally you only want to find data where all 3 conditions are true; you do this by using AND:
where t.name=? AND u.name=? AND v.name=?
Second, why are you joining tables together? Because you need more information. Table POST says that Frank's COUNTRY value is 4; table TAG1 says that 4 means Spain. So we need to "join" these tables together.
The ancient (before 1980, I think) way to join tables is to list more than one table name in the FROM clause, separated by commas. This gives us:
SELECT P.FNAME, P.LNAME, T.NAME As Country, U.NAME As Color, V.NAME As Headgear
FROM POST P, TAG1 T, TAG2 U, TAG3 V
The trouble with this query is that you're not telling it WHICH rows you want, or how they relate to each other. So the database generates something called a "Cartesian Product". It's extremely rare that you want a Cartesian Product - normally this is a HUGE MISTAKE. Even though your database only has 22 rows in it, this SELECT statement is going to return 768 rows of data:
Alex Andrews USA Red None
Alex Andrews USA Red Glasses
Alex Andrews USA Red Hat
Alex Andrews USA Red Monacle
Alex Andrews USA Orange None
Alex Andrews USA Orange Glasses
...
Hank Howard Spain Violet Monacle
That's right, it returns every possible combination of data from the 4 tables. Imagine for a second that the POST table eventually grows to 20000 rows, and the three TAG tables have 100 rows each. The whole database would be less than a megabyte, but the Cartesian Product would have 20,000,000,000 rows of data -- probably about 120 GB of data. Any database engine would choke on that.
So if you want to use the Ancient way of specifying tables, it is VERY IMPORTANT to make sure that your WHERE clause shows the relationship between every table you're querying. This makes a lot more sense:
SELECT P.FNAME, P.LNAME, T.NAME As Country, U.NAME As Color, V.NAME As Headgear
FROM POST P, TAG1 T, TAG2 U, TAG3 V
WHERE P.Country=T.C AND P.Color=U.C AND P.Headgear=V.C
This only returns 8 rows of data.
Using the Ancient way, it's easy to accidentally create Cartesian Products, which are almost always bad. So they revised SQL to make it harder to do. That's the JOIN keyword. Now, when you specify additional tables you can specify how they relate at the same time. The New Way is:
SELECT P.FNAME, P.LNAME, T.NAME As Country, U.NAME As Color, V.NAME As Headgear
FROM POST P
INNER JOIN TAG1 T ON P.Country=T.C
INNER JOIN TAG2 U ON P.Color=U.C
INNER JOIN TAG3 V ON P.Headgear=V.C
You can still use a WHERE clause, too.
SELECT P.FNAME, P.LNAME, T.NAME As Country, U.NAME As Color, V.NAME As Headgear
FROM POST P
INNER JOIN TAG1 T ON P.Country=T.C
INNER JOIN TAG2 U ON P.Color=U.C
INNER JOIN TAG3 V ON P.Headgear=V.C
WHERE P.P=?
If you call this and pass in the value 6, you get only one row back:
Fname Lname Country Color Headgear
----- ------ ------- ------ --------
Frank Farkle Spain Orange None
As was mentioned in the comments, you are looking for an ON clause.
SELECT * FROM TEST1
INNER JOIN TEST2 ON TEST1.A = TEST2.A AND TEST1.B = TEST2.B ...
See example usage of join here:
http://en.wikibooks.org/wiki/Java_Persistence/Relationships#Join_Fetching