How can I join multiple views into a single view - sql

I have a query that has multiple select statements to generate several different sets of results. It's basically a set of 4 separate queries. What I need to do, though, is to have these separate results be joinable into a the 4th query.
From what I can tell, I will need to make the separate queries into individual views so that they're all existing within a single query but I'm not sure how to do this.
I'm using Microsoft SQL Server Management Studio 2010
Query 1 creates a result with the following columns:
AgencyID | Agency | Address | City
Query 2 creates a result with these columns:
AgentID | AgencyID | Name | Address
Query 3 creates a result with these columns:
InsuredID | PolicyID | Name | Company
Query 4 creates a result with these columns:
PolicyID | AgencyID | AgentID | InsuredID
Eeach query has a full set of SELECT, FROM, WHERE and ORDER BY/GROUP BY statements. I need to join the results of the 1st three queries (views?) into the view created by the 4th query based on the columns in there.
I know how to set the joins up once I have the views able to be referenced and joined. What I don't know how to do, however is get them into a format where that can happen.
I want to put all of that together into a single table view so that every row shows the policy info along with the corresponding agent data, insured data, and agency data. Is this an efficient or even possible way to do it?
INSERT INTO #Agency (AgencyID, Agency, Address, City)
SELECT
FROM
WHERE
INSERT INTO #Agent (AgentID, AgencyID, Name, Address)
SELECT
FROM
WHERE
INSERT INTO #Insured (InsuredID, PolicyID, Name, Company)
SELECT
FROM
WHERE
INSERT INTO #Policy (PolicyID, AgencyID, AgentID, InsuredID)
SELECT
FROM
WHERE
SELECT *
FROM #Policy p
JOIN #Agency ay ON ay.AgencyID = p.AgencyID
JOIN #Agent at ON at.AgentID = p.AgentID
JOIN #Insured i ON i.InsuredID = p.InsuredID
Is there a better way to do it or does this seem like a viable route to take? I left out the details of the select, where, and other stuff because they're not relevant to this specific question.

There are several different ways you could do this.
You can do it the way you've laid out.
You could use Common Table Expressions to pull all four precursor queries into your final query.
You could encapsulate the precursor queries in inline table-valued functions and then join them.
You could encapsulate the precursor queries into views and then join them.
There may be minor differences in query efficiency based on the method you choose; this will depend somewhat on the specifics of what you're doing in the precursor queries.

Related

MS Access SQL Query merging two different fields from separate tables shows reference ID's instead of actual values

I have two separate tables in my access database, which both use a third table as the reference for one particular field on each table. The data is entered onto the different tables by separate forms. Then I have several queries that then reference those particular fields that count and show unique values. Those queries show the actual values, then I created an sql query that does the same thing, only it shows the reference ID instead of the value in the actual field.
table ODI----------table CDN----------reference table
id RHA---------id CHA----------------id HA
1 blank----------1 radio---------------1 internet
2 internet-------2 tv------------------2 radio
3 referral-------3 radio---------------3 referral
4 tv-------------4 blank---------------4 repeat customer
5 blank----------5 internet------------5 tv
6 internet-------6 referral------------6 employee
7 referral-------7 referral------------7 social media
this is the code I am trying to make work.
SELECT m.[Marketing Results], Count(*) AS [Count]
FROM (SELECT RHA as [Marketing Results] FROM ODI
UNION ALL
SELECT CHA as [Marketing Results] FROM CDN) AS m
GROUP BY m.[Marketing Results]
HAVING (((m.[Marketing Results]) Is Not Null))
ORDER BY Count(*) DESC;
and what my desired result is,
Marketing Results--Counts
referral------------------4
internet------------------3
radio---------------------2
tv------------------------2
Lookup fields with alias don't show what is actually stored in table. ID is stored, not descriptive alias. Lookup alias will carry into regular queries but Union query only pulls actual stored values. At some point need to include reference table in query by joining on key fields in order to retrieve descriptive alias. Options:
in each UNION query SELECT line, join tables
join UNION query to reference table
join aggregate query to reference table
Most experienced developers will not build lookups in table because of confusion they cause. Also, they are not portable to other database platforms. http://access.mvps.org/Access/lookupfields.htm

duplicated rows in select query

I am trying to run a query to get all the customers from my database. These are my tables in a diagram :
when running the query by joining the table Companies_Customers and the Customers table based on the customerId in both tables(doesn't show in the join table in the pic), I get duplicate rows, which is not the desired outcome.
This is normal from a database standpoint since a Customer can be related to different companies (Companies can share single customer).
My question is how do I get rid of the duplication via SQL.
There can be 2 approaches to your problem.
Either only select data from Customers table:
SELECT * FROM Customers
Or select from both tables joined together, but without CompanyName and with GROUP BY CompanyCustomerId - although I highly suggest the first approach.

Updating column values in a table based on join with another table?

I have two tables called resource and resource_owners.
The resource_owners table contains two columns called resource_id and owner_id.
resource_id | owner_id |
-------------+-----------
The resource table contains two relevant columns: parentresource_id and id.
parentresource_id | id |
-------------------+------
resource_owners.resource_id, resource.id and resource.parentresource_id are all join columns between the two tables. Now what I want to do is the following:
For every row in the resource table, take the value in id, match it with a corresponding resource_owners.resource_id, retrieve the corresponding resource_owners.owner_id value (call it $owner_value), then set resource_owners.owner_id to $owner_value where resource_owners.resource_id equals resource.parentresource_id.
In conversational terms, this is what I want to do: For each resource, I want to re-assign the parent-resource's owner_id to be the resource's owner_id.
I've tried to wrap my head around this problem and it looks like I'll need two different table joins (resource.id with resource_owners.resource_id and resource.parentresource_id with resource_owners.resource_id).
Can someone point me in the right direction? Is what I want even possible with a single query? I'm okay with a PostgreSQL script as well if that works better for my use case.
I'm not sure what database you are using but you should be able to accomplish using the logic below if I understood your question correctly:
UPDATE RESOURCE_OWNER SET
OWNER_ID = UP.OWNER_ID
FROM (SELECT rc.ID, TMP.OWNER_ID FROM (SELECT RSC.ID, ROWRS.OWNER_ID, ROWRS.RESOURCE_ID FROM RESOURCE RSC JOIN RESOURCE_OWNER ROWRS
ON RSC.ID = ROWRS.RESOURCE_ID) TMP JOIN RESOURCE rc on rc.PARENTRESOURCE_ID = TMP.RESOURCE_ID) UP WHERE RESOURCE_OWNER.RESOURCE_ID = UP.ID;

Display blank(null/empty) values in ms access

I have a database in MS Access, and I ran into a problem with empty values. I have 3 tables that are connected to eachother. Lets say Table1 contains people, Table 2 contains Phone numbers, and Table 3 connects table 1 and 2, having both their ID's so I could later see what person has what numbers by using the IDs.
What I want from access is that it would display a person even if he/she doesn't have a number assigned, and also a number when there are no people assigned to it.
Something like this:
Persons_name |Phone_number
--------------------------
Fred | 123
| 222
Anna |
The tables look something like this:
People People_phones Phones
------------- -------------- ------------
ID ID ID
Persons_name People_ID Phone_number
Phones_ID
So far I've managed to get access to show either table 1's null values or table 2's null values, but not both.
As E Mett indicated above, your looking for a full outer join which doesn't handle directly. Here is an example of what he's suggesting:
How do I write a full outer join query in access
JB
In sql jargon what you are looking for is an outer join.
This is unfortunately not available in Ms Access because it is rarely needed.
You should create two queries, one using a left join and the other with a right join.
Then use the UNION keyword to combine the results

SQL JOIN returning multiple rows when I only want one row

I am having a slow brain day...
The tables I am joining:
Policy_Office:
PolicyNumber OfficeCode
1 A
2 B
3 C
4 D
5 A
Office_Info:
OfficeCode AgentCode OfficeName
A 123 Acme
A 456 Acme
A 789 Acme
B 111 Ace
B 222 Ace
B 333 Ace
... ... ....
I want to perform a search to return all policies that are affiliated with an office name. For example, if I search for "Acme", I should get two policies: 1 & 5.
My current query looks like this:
SELECT
*
FROM
Policy_Office P
INNER JOIN Office_Info O ON P.OfficeCode = O.OfficeCode
WHERE
O.OfficeName = 'Acme'
But this query returns multiple rows, which I know is because there are multiple matches from the second table.
How do I write the query to only return two rows?
SELECT DISTINCT a.PolicyNumber
FROM Policy_Office a
INNER JOIN Office_Info b
ON a.OfficeCode = b.OfficeCode
WHERE b.officeName = 'Acme'
SQLFiddle Demo
To further gain more knowledge about joins, kindly visit the link below:
Visual Representation of SQL Joins
Simple join returns the Cartesian multiplication of the two sets and you have 2 A in the first table and 3 A in the second table and you probably get 6 results. If you want only the policy number then you should do a distinct on it.
(using MS-Sqlserver)
I know this thread is 10 years old, but I don't like distinct (in my head it means that the engine gathers all possible data, computes every selected row in each record into a hash and adds it to a tree ordered by that hash; I may be wrong, but it seems inefficient).
Instead, I use CTE and the function row_number(). The solution may very well be a much slower approach, but it's pretty, easy to maintain and I like it:
Given is a person and a telephone table tied together with a foreign key (in the telephone table). This construct means that a person can have more numbers, but I only want the first, so that each person only appears one time in the result set (I ought to be able concatenate multiple telephone numbers into one string (pivot, I think), but that's another issue).
; -- don't forget this one!
with telephonenumbers
as
(
select [id]
, [person_id]
, [number]
, row_number() over (partition by [person_id] order by [activestart] desc) as rowno
from [dbo].[telephone]
where ([activeuntil] is null or [activeuntil] > getdate()
)
select p.[id]
,p.[name]
,t.[number]
from [dbo].[person] p
left join telephonenumbers t on t.person_id = p.id
and t.rowno = 1
This does the trick (in fact the last line does), and the syntax is readable and easy to expand. The example is simple but when creating large scripts that joins tables left and right (literally), it is difficult to avoid that the result contains unwanted duplets - and difficult to identify which tables creates them. CTE works great for me.