SQL subqueries or inner join? - sql

I am building a new web application and have had a basic understanding of sql queries but I am stuck in this particular query.
These are the two tables I will be using this query. The "followingID" in the first table points to the "id" of the second table.
dbo.T_FOLLOWING_GROUP
-id
-groupLookupID
-followingID
-order
dbo.FOLLOWING
-id
-userID
-followingID
I need to get all the rows in dbo.FOLLOWING based on known values that I have of "userID" and "groupLookupID".
Is this enough information to go off of? I know there are ways of doing
`SELECT * FROM dbo.FOLLOWING
WHERE (insert select subquery here)`
Or is there some sort of inner join I need to use?

INNER JOIN
SELECT AnyTableName.AnyColumnName1, AnyTableName.AnyColumnName2, ..... --- out these two tables
FROM dbo.T_FOLLOWING_GROUP INNER JOIN dbo.FOLLOWING
ON dbo.T_FOLLOWING_GROUP.followingID = dbo.FOLLOWING.id
And then you can add WHERE Clause in the end to futher filter the result set
IN Query
SELECT Column1, Column2, Column3, ...........
FROM dbo.T_FOLLOWING_GROUP
WHERE followingID IN (
SELECT DISTINCT id FROM dbo.FOLLOWING
)

To have all in one query (using joins) try this:
SELECT f.*
FROM dbo.FOLLOWING f
LEFT JOIN dbo.T_FOLLOWING_GROUP fg on (f.id=fg.followingID)
WHERE f.userID=xxx AND fg.groupLookupID=yyy
(use your known values in place of xxx and yyy).

Related

join three table in oracle 11g

i have three table to join in select query .. this query not working
select policy_master.POLICY_REFER ,policy_master.CLIENT_NAME ,policy_master.ADRESS ,policy_master.POLICY_CLASS ,policy_master.POLICY_PRODUCT ,policy_master.EXECUTIVE_NAME ,policy_master.COMM_DATE ,
policy_master.EXPIRY_DATE ,policy_master.RENEWAL_DATE ,policy_master.GROSS ,policy_master.FED ,policy_master.FIF ,policy_master.STAMP_DUTY ,policy_master.PERMIUM ,policy_master.DESCRIPTION,
POLICY_INSURER_DETAIL.INSURER_NAME,POLICY_INSURER_DETAIL.POLICY_NUMBER,POLICY_INSURER_DETAIL.P_SHARE,POLICY_INSURER_DETAIL.G_PREMIUM,POLICY_INSURER_DETAIL.BROKER_P,POLICY_INSURER_DETAIL.LEVY,
POLICY_INSURER_DETAIL.LEVY,POLICY_SUBAGENT_DETAIL.SUBAGENT_NAME,POLICY_SUBAGENT_DETAIL.BUSSINES_SHARE,POLICY_SUBAGENT_DETAIL.COMM_P,POLICY_SUBAGENT_DETAIL.COMM_VALUE
from POLICY_MASTER INNER JOIN POLICY_INSURER_DETAIL
on policy_master.policy_refer = POLICY_INSURER_DETAIL.POLICY_REFER and
policy_master.policy_refer = POLICY_SUBAGENT_DETAIL.POLICY_REFER;
Please tell me what i should do
To simplify the answer I've removed all explicit columns and replaced them with select *.
You have only joined two tables. You are refering to policy_subagent_detail table inside a join to policy_insurer_detail (but you're not joining the subagent details table). You should join this table and specify joining conditions in order to be able to retrieve columns from it (as you did in your column list near select keyword).
I've also added table aliases to make your code shorter.
select *
from POLICY_MASTER pm
inner join POLICY_INSURER_DETAIL pid on
pm.policy_refer = pid.POLICY_REFER
inner join POLICY_SUBAGENT_DETAIL psd on -- added join
pm.policy_refer = psd.POLICY_REFER
do inner join of the third table required you missed iton the from clause . thats it .OR you can use where clause like
from table1 a,table2 b,table3 c
where a.colname= b.colname and
b.colname=c.colname.

How to fetch distinct records from SQL Server Compact database

How do I get unique records from multiple tables using SQL Server Compact?
I tried with this SQL statement:
SELECT Tbl_Customer.Name, Tbl_Room.Room_Number
FROM Tbl_Customer
INNER JOIN Tbl_Room ON Tbl_Customer.Customer_number = Tbl_Room.Customer_Number
WHERE Tbl_Customer.Customer_number IN (SELECT DISTINCT Tbl_Customer.Customer_number
FROM Tbl_Customer)
I don't understand why there is this WHERE statement. You are trying to get records from Tbl_Customer that have Customer_number existing in the same table - Tbl_Customer. Without this condition, you can use
SELECT c.Name, r.Room_Number
FROM Tbl_Customer c
INNER JOIN Tbl_Room r ON c.Customer_number = r.Customer_Number
GROUP BY c.Name, r.Room_Number
I hope it helps.
EDIT: In this case SELECT DISTINCT should give the same results and even generate exactly the same query execution plan.

SQL Server 2016 Sub Query Guidance

I am currently working on an assignment for my SQL class and I am stuck. I'm not looking for full code to answer the question, just a little nudge in the right direction. If you do provide full code would you mind a small explanation as to why you did it that way (so I can actually learn something.)
Here is the question:
Write a SELECT statement that returns three columns: EmailAddress, ShipmentId, and the order total for each Client. To do this, you can group the result set by the EmailAddress and ShipmentId columns. In addition, you must calculate the order total from the columns in the ShipItems table.
Write a second SELECT statement that uses the first SELECT statement in its FROM clause. The main query should return two columns: the Client’s email address and the largest order for that Client. To do this, you can group the result set by the EmailAddress column.
I am confused on how to pull in the EmailAddress column from the Clients table, as in order to join it I have to bring in other tables that aren't being used. I am assuming there is an easier way to do this using sub Queries as that is what we are working on at the time.
Think of SQL as working with sets of data as opposed to just tables. Tables are merely a set of data. So when you view data this way you immediately see that the query below returns a set of data consisting of the entirety of another set, being a table:
SELECT * FROM MyTable1
Now, if you were to only get the first two columns from MyTable1 you would return a different set that consisted only of columns 1 and 2:
SELECT col1, col2 FROM MyTable1
Now you can treat this second set, a subset of data as a "table" as well and query it like this:
SELECT
*
FROM (
SELECT
col1,
col2
FROM
MyTable1
)
This will return all the columns from the two columns provided in the inner set.
So, your inner query, which I won't write for you since you appear to be a student, and that wouldn't be right for me to give you the entire answer, would be a query consisting of a GROUP BY clause and a SUM of the order value field. But the key thing you need to understand is this set thinking: you can just wrap the ENTIRE query inside brackets and treat it as a table the way I have done above. Hopefully this helps.
You need a subquery, like this:
select emailaddress, max(OrderTotal) as MaxOrder
from
( -- Open the subquery
select Cl.emailaddress,
Sh.ShipmentID,
sum(SI.Value) as OrderTotal -- Use the line item value column in here
from Client Cl -- First table
inner join Shipments Sh -- Join the shipments
on Sh.ClientID = Cl.ClientID
inner join ShipItem SI -- Now the items
on SI.ShipmentID = Sh.ShipmentID
group by C1.emailaddress, Sh.ShipmentID -- here's your grouping for the sum() aggregation
) -- Close subquery
group by emailaddress -- group for the max()
For the first query you can join the Clients to Shipments (on ClientId).
And Shipments to the ShipItems table (on ShipmentId).
Then group the results, and count or sum the total you need.
Using aliases for the tables is usefull, certainly when you select fields from the joined tables that have the same column name.
select
c.EmailAddress,
i.ShipmentId,
SUM((i.ShipItemPrice - i.ShipItemDiscountAmount) * i.Quantity) as TotalPriceDiscounted
from ShipItems i
join Shipments s on (s.ShipmentId = i.ShipmentId)
left join Clients c on (c.ClientId = s.ClientId)
group by i.ShipmentId, c.EmailAddress
order by i.ShipmentId, c.EmailAddress;
Using that grouped query in a subquery, you can get the Maximum total per EmailAddress.
select EmailAddress,
-- max(TotalShipItems) as MaxTotalShipItems,
max(TotalPriceDiscounted) as MaxTotalPriceDiscounted
from (
select
c.EmailAddress,
-- i.ShipmentId,
-- count(*) as TotalShipItems,
SUM((i.ShipItemPrice - i.ShipItemDiscountAmount) * i.Quantity) as TotalPriceDiscounted
from ShipItems i
join Shipments s on (s.ShipmentId = i.ShipmentId)
left join Clients c on (c.ClientId = s.ClientId)
group by i.ShipmentId, c.EmailAddress
) q
group by EmailAddress
order by EmailAddress
Note that an ORDER BY is mostly meaningless inside a subquery if you don't use TOP.

Update using Distinct SUM

I have found a few good resources that show I should be able to merge a select query with an update, but I just can't get my head around of the correct formatting.
I have a select statement that is getting info for me, and I want to pretty much use those results to Update an account table that matches the accountID in the select query.
Here is the select statement:
SELECT DISTINCT SUM(b.workers)*tt.mealTax as MealCost,b.townID,b.accountID
FROM buildings AS b
INNER JOIN town_tax AS tt ON tt.townID = b.townID
GROUP BY b.townID,b.accountID
So in short I want the above query to be merged with:
UPDATE accounts AS a
SET a.wealth = a.wealth - MealCost
Where MealCost is the result from the select query. I am sure there is a way to put this into one, I just haven't quite been able to connect the dots to get it to run consistently without separating into two queries.
First, you don't need the distinct when you have a group by.
Second, how do you intend to link the two results? The SELECT query is returning multiple rows per account (one for each town). Presumably, the accounts table has only one row. Let's say that you wanted the average MealCost for the update.
The select query to get this is:
SELECT accountID, avg(MealCost) as avg_Mealcost
FROM (SELECT SUM(b.workers)*tt.mealTax as MealCost, b.townID, b.accountID
FROM buildings AS b INNER JOIN
town_tax AS tt
ON tt.townID = b.townID
GROUP BY b.townID,b.accountID
) a
GROUP BY accountID
Now, to put this into an update, you can use syntax like the following:
UPDATE accounts
set accounts.wealth = accounts.wealth + asum.avg_mealcost
from (SELECT accountID, avg(MealCost) as avg_Mealcost
FROM (SELECT SUM(b.workers)*tt.mealTax as MealCost, b.townID, b.accountID
FROM buildings AS b INNER JOIN
town_tax AS tt
ON tt.townID = b.townID
GROUP BY b.townID,b.accountID
) a
GROUP BY accountID
) asum
where accounts.accountid = asum.accountid
This uses SQL Server syntax, which I believe is the same as for Oracle and most other databases. Mysql puts the "from" clause before the "set" and allows an alias on "update accounts".

sql multiple count

I have 3 tables, where the first one's primary key, is the foreign key in the other 2.
I want to extract one field from the first table, and then a count from the other 2, all joined using the pk and fk. This is what I have so far:
SELECT MBDDX_STUDY.STUDY_NAME, COUNT(MBDDX_EXPERIMENT.STUDY_ID) AS NUMBER_OF_EXPERIMENTS
FROM MBDDX_STUDY
INNER JOIN MBDDX_EXPERIMENT
ON MBDDX_STUDY.ID=MBDDX_EXPERIMENT.STUDY_ID
INNER JOIN (SELECT COUNT(MBDDX_TREATMENT_GROUP.GROUP_NO) AS NUMBER_OF_GROUPS
FROM MBDDX_TREATMENT_GROUP)
ON MBDDX_TREATMENT_GROUP.STUDY_ID = MBDDX_STUDY.ID
group by MBDDX_STUDY.STUDY_NAME, MBDDX_TREATMENT_GROUP.STUDY_ID
But, i get an error saying that the MBDDX_TREATMENT_GROUP.STUDY_ID , in the penultimate line is an invalid indentifier. It is a correct table.
Any advise please.
Thanks.
You're getting the error because that column is not in your SELECT, so it can't GROUP BY a field it doesn't have.
The subquery syntax doesn't seem to make any sense to me. You've made a query that counts all rows of MBDDX_TREATMENT_GROUP, independently of the STUDY_ID, and then tries to join it into the table with a join condition that doesn't refer to anything in the subquery's results (and can't, without an alias).
Why not use a simple join? Assuming MBDDX_EXPERIMENT also has a primary key ID, you can do it with a COUNT-DISTINCT:
SELECT
MBDDX_STUDY.ID, MBDDX_STUDY.STUDY_NAME,
COUNT(DISTINCT MBDDX_EXPERIMENT.ID) AS NUMBER_OF_EXPERIMENTS
COUNT(DISTINCT MBDDX_TREATMENT_GROUP.GROUP_NO) AS NUMBER_OF_GROUPS
FROM
MBDDX_STUDY
INNER JOIN MBDDX_EXPERIMENT ON MBDDX_EXPERIMENT.STUDY_ID=MBDDX_STUDY.ID
INNER JOIN MBDDX_TREATMENT_GROUP ON MBDDX_TREATMENT_GROUP.STUDY_ID=MBDDX_STUDY.ID
GROUP BY
MBDDX_STUDY.ID, MBDDX_STUDY.STUDY_NAME
(MBDDX_STUDY.STUDY_NAME technically shouldn't be necessary to include in the GROUP BY expression according to ANSI SQL as it has a functional dependency on STUDY_ID. However it is necessary on Oracle, which can't spot the dependency.)
You don't need to group by this field (MBDDX_TREATMENT_GROUP.STUDY_ID). It should be just group by MBDDX_STUDY.STUDY_NAME
If my understanding is correct,You need a record from first table and have the count of related records in the other two tables.Here is the answer
SQL:Getting count from many tables for a user record in USER table.Whats the best approach?
It looks like you need to alias the second subquery and need to include something to join on.
It also looks like you aren't using the count you have in the subquery as well.
Try this out:
SELECT MBDDX_STUDY.STUDY_NAME
, COUNT(MBDDX_EXPERIMENT.STUDY_ID) AS NUMBER_OF_EXPERIMENTS
FROM MBDDX_STUDY
INNER JOIN MBDDX_EXPERIMENT
ON MBDDX_STUDY.ID=MBDDX_EXPERIMENT.STUDY_ID
INNER JOIN (SELECT STUDY_ID, COUNT(MBDDX_TREATMENT_GROUP.GROUP_NO) AS NUMBER_OF_GROUPS
FROM MBDDX_TREATMENT_GROUP GROUP BY MBDDX_TREATMENT_GROUP.STUDY_ID) xx
ON xx.STUDY_ID = MBDDX_STUDY.ID
GROUP BY MBDDX_STUDY.STUDY_NAME, xx.STUDY_ID
For what you really want to do, you want OUTER JOINs.
WITH number_of_experiments
AS ( SELECT study_id
, count ( * ) CNT
FROM MBDDX_EXPERIMENT
group by study_id )
, number_of_groups
as ( select study_id
, count ( * ) CNT
FROM mbddx_treatment_group
group by study_id )
select study_name
, coalesce(noex.cnt,0)
, coalesce(notr.cnt,0)
from mbddx_study
outer join number_of_experiments
as noex
using ( study_id )
outer join number_of_groups
as nogr
using ( study_id )