Using Union to display two columns - union

I am trying to use UNION to collect data from two tables, however, the results combine both rows of information into one long column. I've spent a few hours researching unions and I cannot find a code that separates the result! I am using microsoft Access, and would like to use UNION if it possible. Please help...
My code is:
SELECT Suburb
FROM Customer
UNION
SELECT TotalPaid
FROM SalesOrder
ORDER BY Suburb;
An example of my result is:
Suburb
0
128
Brighton
Kings Cross
But I need it to show:
Suburb Total Paid
Brighton 0
Kings Cross 128

No need of Union,Hope you have relation on suburb between two tables.
SELECT c.Suburb ,TotalPaid
FROM Customer as c
left join SalesOrder as s on c.Suburb = s.Suburb
ORDER BY c.Suburb;

Related

Sum field(s) from one table in another table, summing from 3 different tables

I have an Access database with customer IDs. Each customer can have multiple orders and each order can be of a different type. I have three separate tables (Online, In-store, Payment Plan) for each order type with various amounts from each order, all are related to a customer ID. In one of the tables, there are two types of order types that amounts must be maintained separately withing the same table. I want to sum each order type in another table called Totals. I can successfully create a query to get the sums for each type based on the customer ID but I am not sure how to pull those values in my Totals table. The scenario below is repeated for multiple customers and each type is its own table---the payment plans are in a table together. I have historical data so I am limited to how I can manipulate as far as merging fields and what not.
Customer ID#: 1
Order Type: Online
Online Amount: $20.00
Order Type: Online
Online Amount: $40.00
Sum of Online Amount: $60.00
Order Type: In-store
Online Amount: $35.00
Order Type: In-store
Online Amount: $60.00
Sum of In-Store Amount: $95.00
Order Type: Payment Plan
Payment Plan 1 Amount: $30.00
Payment Plan 1 Amount: $23.00
Sum of Payment Plan 1 Amount: $53.00
Order Type: Payment Plan 2
Payment Plan 2 Amount: $35.00
Payment Plan 2 Amount: $30.00
Sum of Payment Plan 2 Amount: $65.00
In my Totals table I have a field for each type that sums the amount spent by each customer ID and then a field where all of their order types are summed into one overall total field.
I am learning as I go so any help/example is appreciated. Thank you.
Having separate tables for your different order types doesn't help. For a database it would be better to have a single table for all sales with a sale_type field.
You don't describe exactly what your tables look like, so I've had to make a couple of assumptions. If your tables contain an OrderType field then you can create a Union query to join all your sales together:
SELECT CustomerID
, OrderType
, Amount
FROM Online
UNION ALL SELECT CustomerID
, OrderType
, Amount
FROM [In-Store]
UNION ALL SELECT CustomerID
, OrderType
, Amount
FROM [Payment Plan]
If you don't have an OrderType you can hard-code the values into the query:
SELECT CustomerID
, "Online" AS OrderType
, Amount
FROM Online
UNION ALL SELECT CustomerID
, "In-Store"
, Amount
FROM [In-Store]
UNION ALL SELECT CustomerID
, "Payment Plan"
, Amount
FROM [Payment Plan]
Note - The field name is declared for the OrderType in the first Select block. You could do it in each block, but Access only looks at the first.
Like all queries, the results come in table form and can be treated as such. So now we need to list the CustomerName (I'm assuming you have a Customers table), the OrderType and the sum of the amount for that Customer & OrderType.
SELECT CustomerName
, OrderType
, SUM(Amount)
FROM Customers INNER JOIN
(
SELECT CustomerID
, OrderType
, Amount
FROM Online
UNION ALL SELECT CustomerID
, OrderType
, Amount
FROM [In-Store]
UNION ALL SELECT CustomerID
, OrderType
, Amount
FROM [Payment Plan]
) T1 ON Customers.CustomerID = T1.CustomerID
GROUP BY CustomerName
, OrderType
All sales in your three tables will have a customer within the customers table so we can use an INNER JOIN to return only records where the value appears in both tables (Customers table & result of query table).
The UNION QUERY is wrapped in brackets and given the name T1and joined to the Customers table on the CustomerID field.
We group all fields that aren't part of an aggregate function, so group on CustomerName and OrderType and sum the Amount field.
This is all you really need to do - let the query run each time you want the totals to get the most up to date values. There's shouldn't be a need to push the results to a Totals table as that will be out of date as soon as you make a new sale (or someone returns something).
If you really want to INSERT these figures into a Total table just add a first line to the SQL:
INSERT INTO Total (CustomerName, OrderType, Amount)
Here is a dirty workaround, though I think there might be a more direct solution to it.
You could create an output table (I broke it down to ID, Online, InStore and Total) and use DSum functions within an UPDATE query.
UPDATE tbl_Totals SET
Total_InStore = DSum("Amount", "tbl_InStore", "Customer_ID = " & Customer_ID),
Total_Online = DSum("Amount", "tbl_Online", "Customer_ID = " & Customer_ID),
Total = DSum("Amount", "tbl_InStore", "Customer_ID = " & Customer_ID) + DSum("Amount", "tbl_Online", "Customer_ID = " & Customer_ID)

How to construct an SQL query for finding which company has the most employees?

I have the following tables and I would like to find the company which has the most workers. I am fairly new to sql and I would like some help on constructing the query. Any briefing would be appreciated on which keywords to use or how to begin with writing the query. I would like to
“Find the company that has the most workers.”
worker(worker_name, city, street)
work for(worker_name, company_name, salary)
company(company_name, city)
manages( worker_name, manage_name)
this will get you the company with the most employees in it.
select top 1 company_name,
count(*) as nbr_of_employees
from work-for
group by company_name
order by 2 desc
For more detailed answer please add sample data to your question and expected result.
how it works:
the group by company_name will group all records with the same company_name togheter. Because of that the count(*) will give you the number of records in work-for for each group. (thus all workers for each company)
the order by 2 desc will make sure that the company-name with the most employees is on top of the lists
Finally, the top 1 in the select will only return the first record in that list

How to join two tables based on Grouping of 1 column in both the tables

I have come up a situation which is not easy to explain in sentence so i will go ahead and give the complete scenario here.
I have one result set like the below :-
It shows header_equipment_id(s) in a group of jil_equipment_id,relationship_name,cell_group.. For example 3159398,4622903 lies in one group.
The other result set is given below, This is the table where i want to update 3 columns namely Is_Applicable_Price,prc_content_rid,prc_type_name
If you notice clearly, You will find the same header_equipment_id column here. If you group it with the result found above, You will find 3 different groups for. But out of those 3 groups, one group is red, It is red because they belong to different cell_group/relationship_name.
**
Yellow and green are passed scenario and Red, Blue are fail.
**
I want to update the columns Is_Applicable_Price,prc_content_rid,prc_type_name if the Group of header_equipment_id(s) fall under the same cell_group and relationship_name.
So the final result set would look something like below -
Please help me with any inputs if possible. It's a situation where i know one single query won't work. But i will need to have multiple Temp tables for the transformation. But this is the shortest i have came across.
I am using Microsoft sql server 2012.
Please help. Even a small hint would be of great help to me. Thanks in advance.
It seems that the only thing the 2 tables have in common is that a cell_group can have a one or more rows of header_equipment_id. If we can generate a unique value based on header_equipment_id then we can join the 2 tables on this value. Note I have used a simple division , you may wish to check that this method is unique enough for your purposes.
/*create table a
(jil_equimentid int,relationship_name varchar(20),header_equipment_id int,
smart_equipment_id int,cell_group int,new_price_flag int,is_applicable_price int,prc_content_rid int,prc_type_name varchar(20))
truncate table a
insert into a values
(1282977,'default',3159398,1282977,3,1,1,106347924,'New Price'),
(1282977,'default',4622903,1262578,3,1,1,106347924,'New Price'),
(1282977,'default',1659861,1282977,6,1,1,106347925,'New Price'),
(1282977,'default',4622904,1282977,6,1,1,106347925,'New Price')
go
drop table t
go
create table t
(jil_equimentid int,relationship_name varchar(20),header_equipment_id int,
smart_equipment_id int,cell_group int,new_price_flag int,is_applicable_price int,prc_content_rid int,prc_type_name varchar(20))
truncate table t
insert into t values
(1282977,'128297711111 default',4622903,1282977,1,1,null,null,null),
(1282977,'128297711211 default',3159398,1262578,2,1,null,null,null),
(1282977,'128297712111 default',4622904,1282977,4,1,null,null,null),
(1282977,'128297712211 default',1659861,1282977,5,1,null,null,null),
(1282977,'128297711101 default',3159398,1262578,1,1,null,null,null),
(1282977,'128297711101 default',4622903,1282977,1,1,null,null,null),
(1282977,'default' ,3159398,1262578,2,1,null,null,null),
(1282977,'default' ,4622903,1282977,2,1,null,null,null),
(1282977,'128297711101 default',1659861,1262577,3,1,null,null,null),
(1282977,'128297711101 default',4622904,1282977,3,1,null,null,null),
(1282977,'default' ,1659861,1262577,4,1,null,null,null),
(1282977,'default' ,4622904,1262577,4,1,null,null,null)
*/
DROP TABLE #TEMPA;
;WITH CTE AS
(SELECT a.cell_group,
sum(a.header_equipment_id / 10000000.0000) uniqueval
from a
group by a.cell_group
)
SELECT DISTINCT CTE.UNIQUEVAL ,IS_APPLICABLE_PRICE ,PRC_CONTENT_RID ,PRC_TYPE_NAME
INTO #TEMPA
FROM CTE
JOIN A ON A.CELL_GROUP = CTE.CELL_GROUP
;WITH CTE AS
(
SELECT t.relationship_name,t.cell_group,
sum(t.header_equipment_id / 10000000.0000) uniqueval
from t
group by t.relationship_name,t.cell_group having count(*) > 1
)
SELECT T.*,CTE.UNIQUEVAL,ta.*
FROM CTE
JOIN T ON T.RELATIONSHIP_NAME = CTE.RELATIONSHIP_NAME AND T.CELL_GROUP = CTE.CELL_GROUP
join #tempa ta on ta.uniqueval = cte.uniqueval

Detecting multiple records associated with a table

I have a SQL Server 2008 database that has two tables. These two tables are CoreGroup and CoreGroupMember. Please note, I did not setup these tables. Regardless, the table structure is:
CoreGroup
---------
ID
GroupMember1MemberName
GroupMember2MemberName
GroupMember3MemberName
GroupMember4MemberName
CoreGroupMember
---------------
ID
CoreGroupID
MemberName
I need to determine how many CoreGroup records are associated with a CoreGroupMember with a specific MemberName. There is one catch that is really throwing me for a loop though. Some CoreGroup records only have one member associated with them. I need to retrieve the CoreGroup records that have multiple CoreGroupMember records where at least one of the records has the specific MemberName. I can't seem to figure out the multiple record part. Can someone please help me?
Thank you!
I'll take a stab at it hoping I've understood the requirements correctly. First, I use a cte to find all groups with multiple members, then use that result set to find groups with your specific member.
with cteMultipleMembers as (
select cg.ID, COUNT(*) as MemberCount
from CoreGroup cg
inner join CoreGroupMember cgm
on cg.ID = cgm.CoreGroupID
group by cg.ID
having COUNT(*) > 1
)
select mm.ID
from cteMultipleMembers mm
inner join CoreGroupMember cgm
on mm.ID = cgm.CoreGroupID
and cgm.MemberName = #YourMemberName

How to fetch an object graph at once?

I'm reading a book, where the author talks about fetching an row + all linked parent rows in one step. Like fetching an order + all it's items all at once. Okay, sounds nice, but really: I've never seen an possibility in SQL to ask for - lets say - one order + 100 items? How would this record set look like? Would I get 101 rows with merged fields of both the order and the item table, where 100 rows have a lot of NULL values for the order fields, while one row has a lot of NULL values for the item fields? Is that the way to go? Or is there something much cooler? I mean... I never heard of fetching arrays onto a field?
A simple JOIN would do the trick:
SELECT o.*
, i.*
FROM orders o
INNER JOIN order_items i
ON o.id = i.order_id
The will return one row for each row in order_items. The returned rows consist of all fields from the orders table, and concatenated to that, all fields from the order_items table (quite literally, the records from the tables are joined, that is, they are combined by record concatenation)
So if orders has (id, order_date, customer_id) and order_items has (order_id, product_id, price) the result of the statement above will consist of records with (id, order_date, customer_id, order_id, product_id, price)
One thing you need to be aware of is that this approach breaks down whenever there are two distinct 'detail' tables for one 'master'. Let me explain.
In the orders/order_items example, orders is the master and order_items is the detail: each row in order_items belongs to, or is dependent on exactly one row in orders. The reverse is not true: one row in the orders table can have zero or more related rows in the order_items table. The join condition
ON o.id = i.order_id
ensures that only related rows are combined and returned (leaving out the condition would retturn all possible combinations of rows from the two tables, assuming the database would allow you to omit the join condition)
Now, suppose you have one master with two details, for example, customers as master and customer_orders as detail1 and customer_phone_numbers. Suppose you want to retrieve a particular customer along with all is orders and all its phone numbers. You might be tempted to write:
SELECT c.*, o.*, p.*
FROM customers c
INNER JOIN customer_orders o
ON c.id = o.customer_id
INNER JOIN customer_phone_numbers p
ON c.id = p.customer_id
This is valid SQL, and it will execute (asuming the tables and column names are in place)
But the problem is, is that it will give you a rubbish result. Assuming you have on customer with two orders (1,2) and two phone numbers (A, B) you get these records:
customer-data | order 1 | phone A
customer-data | order 2 | phone A
customer-data | order 1 | phone B
customer-data | order 2 | phone B
This is rubbish, as it suggests there is some relationship between order 1 and phone numbers A and B and order 2 and phone numbers A and B.
What's worse is that these results can completely explode in numbers of records, much to the detriment of database performance.
So, JOIN is excellent to "flatten" a hierarchy of items of known depth (customer -> orders -> order_items) into one big table which only duplicates the master items for each detail item. But it is awful to extract a true graph of related items. This is a direct consequence of the way SQL is designed - it can only output normalized tables without repeating groups. This is way object relational mappers exist, to allow object definitions that can have multiple dependent collections of subordinate objects to be stored and retrieved from a relational database without losing your sanity as a programmer.
This is normally done through a JOIN clause. This will not result in many NULL values, but many repeated values for the parent row.
Another option, if your database and programming language support it, it to return both result sets in one connection - one select for the parent row another for the related rows.

Resources