Querying a SQL Query for Distinct Records - sql

I have a SQL Query that joins 3 tables and pulls 3 total columns out of them. I was try to figure out how to Query that Query to get distinct records from only one of the columns. Here is what I have so far
Select Distinct Make.NAME
From
(
Select MakeModel.MAKE_ID, Make.NAME, Vehicle.MODEL_YR
From NagsInfo.dbo.Make
INNER JOIN NagsInfo.dbo.MakeModel
on Make.MAKE_ID = MakeModel.MAKE_ID
INNER JOIN NagsInfo.dbo.Vehicle
on MakeModel.MAKE_MODEL_ID = Vehicle.MAKE_MODEL_ID
Where Vehicle.MODEL_YR = #YEAR
)
I keep getting multiple different syntax errors, I believe the most recent one telling me that the parentheses were incorrect, but everywhere I looked they are required for Sub queries.

Why use a subquery at all? Why not just do:
SELECT DISTINCT M.NAME
FROM NagsInfo.dbo.Make M
JOIN NagsInfo.dbo.MakeModel MM ON M.MAKE_ID = MM.MAKE_ID
JOIN NagsInfo.dbo.Vehicle V ON MM.MAKE_MODEL_ID = V.MAKE_MODEL_ID
WHERE V.MODEL_YR = #YEAR

Related

Get all columns from other tables with a distinct

I am doing a distinct to filter by 2 columns, but I need it to bring me all the columns of the query, in this case it only brings me "idMes" and "idAnio", I need it to show me the other columns as well.
How could I do it?
this is my sentence:
SELECT DISTINCT e.idMes, e.idAnio FROM expensas as e INNER JOIN anios as a on e.idAnio = a.idAnio INNER JOIN meses as m on e.idMes = m.idMes;
Select * gives you all columns

Problems getting desired output from SQL JOIN Query

Trying to extract data from multiple SQL tables. I have a main table and a couple of sub-tables. I want to get all the rows from the main table given a condition and add some fields from the sub-tables. I figured an OUTER JOIN should have worked but I am not getting the entire data.
When I run a COUNT on the main table with the condition I get ~10k rows which is what I am expecting to get once I join the other tables. I understand that I will get NULL values on some row entries.
This is the query I came up with but I am only getting partial results
SELECT main_table.group_id, main_table.floor, sub_table1.Name, sub_table2.base
FROM main_table
LEFT JOIN ON main_table.group_id =sub_table1.group_id
LEFT JOIN ON main_table.group_id =sub_table2.group_id
WHERE main_table.year = 2000 AND sub_table1.year = 2000
AND sub_table2.year = 2000 AND main_table.group = 'C'
I am expecting to see a collection of about 10k rows since that is the number I get when only querying the main table with where clause.
SELECT COUNT(*) FROM main_table WHERE year = 2000 AND group = 'C';
Your where clause is filtering out the extra rows from the outer joins -- effectively turning them into inner joins.
Conditions on all but the first table should be in the on clauses. But I would phrase this as:
SELECT main_table.group_id, main_table.floor, sub_table1.Name, sub_table2.base
FROM main_table LEFT JOIN
sub_table1
ON main_table.group_id = sub_table1.group_id AND
main_table.year = sub_table1.year LEFT JOIN
sub_table2
ON main_table.group_id = sub_table2.group_id AND
main_table.year = sub_table2.year
WHERE main_table.year = 2000 AND main_table.group = 'C';
You want the years to be equal, so that should really be a JOIN condition. Then you only need to specify the year once in the WHERE clause.
Whatever condition in ON clause is used for join and condition in WHERE clause are used to filter out final result.
Apart from gordon's answer, If your requirement is to include different/same years in joins then you can use following query:
SELECT main_table.group_id, main_table.floor, sub_table1.Name, sub_table2.base
FROM main_table LEFT JOIN
sub_table1
ON (main_table.group_id = sub_table1.group_id AND
sub_table1.year = 2000) LEFT JOIN
sub_table2
ON (main_table.group_id = sub_table2.group_id AND
sub_table2.year = 2000)
WHERE main_table.year = 2000 AND main_table.group = 'C';
Cheers!!

SUM a column count from two tables

I have this simple unioned query in SQL Server 2014 where I am getting counts of rows from each table, and then trying to add a TOTAL row at the bottom that will SUM the counts from both tables. I believe the problem is the LEFT OUTER JOIN on the last union seems to be only summing the totals from the first table
SELECT A.TEST_CODE, B.DIVISION, COUNT(*)
FROM ALL_USERS B, SIGMA_TEST A
WHERE B.DOMID = A.DOMID
GROUP BY A.TEST_CODE, B.DIVISION
UNION
SELECT E.TEST_CODE, F.DIVISION, COUNT(*)
FROM BETA_TEST E, ALL_USERS F
WHERE E.DOMID = F.DOMID
GROUP BY E.TEST_CODE, F.DIVISION
UNION
SELECT 'TOTAL', '', COUNT(*)
FROM (SIGMA_TEST A LEFT OUTER JOIN BETA_TEST E ON A.DOMID
= E.DOMID )
Here is a sample of the results I am getting:
I would expect the TOTAL row to display a result of 6 (2+1+3=6)
I would like to avoid using a Common Table Expression (CTE) if possible. Thanks in advance!
Since you are counting users with matching DOMIDs in the first two statements, the final statement also needs to include the ALL_USERS table. The final statement should be:
SELECT 'TOTAL', '', COUNT(*)
FROM ALL_USERS G LEFT OUTER JOIN
SIGMA_TEST H ON G.DOMID = H.DOMID
LEFT OUTER JOIN BETA_TEST I ON I.DOMID = G.DOMID
WHERE (H.TEST_CODE IS NOT NULL OR I.TEST_CODE IS NOT NULL)
I would consider doing a UNION ALL first then COUNT:
SELECT COALESCE(TEST_CODE, 'TOTAL'),
DIVISION,
COUNT(*)
FROM (
SELECT A.TEST_CODE, B.DIVISION
FROM ALL_USERS B
INNER JOIN SIGMA_TEST A ON B.DOMID = A.DOMID
UNION ALL
SELECT E.TEST_CODE, F.DIVISION
FROM BETA_TEST E
INNER JOIN ALL_USERS F ON E.DOMID = F.DOMID ) AS T
GROUP BY GROUPING SETS ((TEST_CODE, DIVISION ), ())
Using GROUPING SETS you can easily get the total, so there is no need to add a third subquery.
Note: I assume you want just one count per (TEST_CODE, DIVISION). Otherwise you have to also group on the source table as well, as in #Gareth's answer.
I think you can achieve this with a single query. It seems your test tables have similar structures, so you can union them together and join to ALL_USERS, finally, you can use GROUPING SETS to get the total
SELECT ISNULL(T.TEST_CODE, 'TOTAL') AS TEST_CODE,
ISNULL(U.DIVISION, '') AS DIVISION,
COUNT(*)
FROM ALL_USERS AS U
INNER JOIN
( SELECT DOMID, TEST_CODE, 'SIGNMA' AS SOURCETABLE
FROM SIGMA_TEST
UNION ALL
SELECT DOMID, TEST_CODE, 'BETA' AS SOURCETABLE
FROM BETA_TEST
) AS T
ON T.DOMID = U.DOMID
GROUP BY GROUPING SETS ((T.TEST_CODE, U.DIVISION, T.SOURCETABLE), ());
As an aside, the implicit join syntax you are using was replaced over a quarter of a century ago in ANSI 92. It is not wrong, but there seems to be little reason to continue to use it, especially when you are mixing and matching with explicit outer joins and implicit inner joins. Anyone else that might read your SQL will certainly appreciate consistency.

SQL joining tables and having where clause from the joined table

Currently not working...
SELECT COUNT(*) FROM CLICKHISTORY
INNER JOIN EDSC ON CLICKHISTORY.SOURCEID = EDSC.SOURCEID
WHERE EDSC.DOMAIN='SCMDomain';
Currently this returns Count = 0, and in words I want to merge two tables on the sourceID's and then filter out all data so we are only left with EDSC.DOMAIN= 'SCMDomain.
EDSC and CLICKHISTORY are the two tables. Thanks
Here is an alternative way of writing it without the JOIN:
SELECT COUNT(*)
FROM CLICKHISTORY
WHERE CLICKHISTORY.SOURCEID IN (
SELECT EDSC.SOURCEID
FROM EDSC
WHERE EDSC.DOMAIN = 'SCMDomain')

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".