Will these two MS queries give me the same output? - sql-server

I'm updating some queries as an assignment for work. The bottom query is the updated version with different syntax, and the top is the old query. I just want to double check that the two queries will end with the same results:
SELECT a.breed
FROM dogs a, cats b, fish c
WHERE a.breed = b.breed AND a.tail = 0 AND b.size = c.size AND c.gills = 0 AND c.fin = #fin
----
SELECT a.breed
FROM dogs a
INNER JOIN cats b ON a.breed = b.breed
INNER JOIN fish c ON b.size = c.size
WHERE c.gills = 0 AND a.tail = 0 AND c.fin = #fin
Edit 1: fixed the format of the question to better represent what I meant. I changed the names of the tables and columns just in case.

Yes, these queries will return the same results.

Related

Performing COUNT() on a computed Column from a VIEW

So all I want to do is have a view that shows how many kid between and including the age of 5 - 18 are in each family. I AM USING SQL SERVER.
The view I Have written to get the Family Members Ages is
CREATE VIEW VActiveMembers
AS
SELECT
TM.intMemberID AS intMemberID,
TM.strFirstName AS strFirstName,
TM.strLastName AS strLastName,
TM.strEmailAddress AS strEmailAddress,
TM.dtmDateOfBirth AS dtmDateOfBirth,
FLOOR(DATEDIFF(DAY, dtmDateOfBirth, GETDATE()) / 365.25) AS intMemberAge
FROM
TMembers AS TM
WHERE
TM.intStatusFlagID = 1
intStatusFlag = 1 is just a flag that means the member is active.
Now I have tried for about 3ish hours to figure this out but I cannot figure it out. Here is the one where instead of trying to get the solution in one fowl swoop I tried to step wise it, but then I still didn't get the result I wanted.
As you can see I didn't use the view where I calculated the AGE from because the "Multi-part Identifier could not be bound" I have seen that error but I couldn't get it to go away in this case. Ideally I would like the count to be performed on the VIEW instead of recalculating the ages all over again
CREATE VIEW VActiveFamilyMembersK12Count
AS
SELECT
TF.intParishFamilyID,
COUNT(DATEDIFF(DAY, dtmDateOfBirth, GETDATE()) / 365) AS intMemberAgeCount
FROM
TFamilies AS TF
INNER JOIN
TFamilyMembers AS TFM
INNER JOIN
VActiveMembers AS vAM ON (TFM.intMemberID = vAM.intMemberID)
ON (TFM.intParishFamilyID = TF.intParishFamilyID)
WHERE
TF.intStatusFlagID = 1
GROUP BY
TF.intParishFamilyID
I wanted to just get a count using the age calculation just to see If I could get a correct count of members in a family, then I could start building upon that to get a count of members of a certain age. The result I get back is 2 but there are guaranteed 3 members to each family.
The result I am looking For is this
Family_ID | K12Count
-----------------------------
1001 | 2
1002 | 0
1003 | 1
1004 | 0
Here is a list of resources I looked up trying to figure this out, maybe one of them is in fact the answer and I just don't see it, but I am at a loss at the moment.
SQL Select Count from below a certain age
How to get count of people based on age groups using SQL query in Oracle database?
Count number of user in a certain age's range base on date of birth
Conditional Count on a field
http://timmurphy.org/2010/10/10/conditional-count-in-sql/
*** EDIT ***
CREATE VIEW VActiveFamilyMembersK12Count
AS
SELECT
TF.intParishFamilyID,
SUM(CASE WHEN intMemberAge >= 5 AND intMemberAge <= 18 THEN 1 ELSE 0 END) AS intK12Count
FROM
TFamilies AS TF
INNER JOIN TFamilyMembers AS TFM
INNER JOIN VActiveMembers AS vAM
ON (TFM.intMemberID = vAM.intMemberID)
ON (TFM.intParishFamilyID = TF.intParishFamilyID)
WHERE
TF. intStatusFlagID = 1
GROUP BY
TF.intParishFamilyID
GO
THIS IS THE SOLUTION ABOVE.
Conditional count is the way to go.
Something like:
SELECT intParishFamilyID,
COUNT(CASE WHEN intMemberAge >=5 and intMemberAge <=18 THEN 1 ELSE 0 END)
FROM
TFamilies AS TF
INNER JOIN TFamilyMembers AS TFM
INNER JOIN VActiveMembers AS vAM
ON (TFM.intMemberID = vAM.intMemberID)
ON (TFM.intParishFamilyID = TF.intParishFamilyID)
WHERE
TF. intStatusFlagID = 1
GROUP BY
TF.intParishFamilyID

How to set up a dataset filter to check for multiple criteria

I have data that I want to filter based on if it matches 1 of 3 criteria.
Sponsor Rating = 0
IT Rating = 0
Evaluation code = NC or - (but there are multiple codes and we do not want to leave them out since they may fit one of the other criteria)
How can I do this without adjusting the Stored Procedure?
So ideally I would like to say
If a record has an eval code of NC or - then I want to see it no matter the ratings
If a record has either an IT rating or Spnsr rating equal to 0 then I want to see it regardless of the eval code
I have tried the following in the dataset filters:
Eval_code in NC, - Text
IT rating AND Spnsr Rating = 0 Integer
But this is returning only the record that meet that criteria. There are records with other Eval codes that have IT and Spnsr rating = 0 As well as records that have IT and Sponsr ratings >0 that have a eval code of NC or -.
Thanks
Using AND in the where clause requires that all where clauses are met. Using OR requires that only one be met. If you want condition A, B, or C then
Where condition1 = A
OR condition2 = B
OR condition3 = C
If you want Condition A and B or C then
Where condition1 = A
AND (condition2 = B OR condition3 = C)
In your case
Where [EvalCode] IN ('NC','-')
OR [SponsorRating] = 0
OR [ITRating] = 0

convert letters to numbers or vice versa

TRADE_SIDE values are stored in DB with values 1 or 2.
On the other hand, SPOT_SIDE values are stored with equivalent A and B values in DB.
I need to find a way to compare these values in the where clause when querying the DB. 1 for A and 2 for B.
Do you have an idea?
Simple CASE EXPRESSION will do the trick :
SELECT * FROM trade_side t
INNER JOIN spot_side s
ON(CASE WHEN t.<YourColumn> = 1 THEN 'A' ELSE 'B' END = s.<YourColumn>)
This query will join both tables together on(1 = a,2 = b) . If you have more then 2 values, you should add another WHEN .

Using SQL to find entries that were originally X and later changed to Y

I recently started using SQL for work and don't have much experience of it so I'm sorry if this is a ridiculous question.
I'm looking for an entry that was originally listed as X but was then later changed to Y, I figure that a nested sub query is the way to go but the one I'm trying doesn't seem to use the nested bit.
Here is the code I'm trying
SELECT *
FROM [HOME].[dba].[ARCHIVE]
where FRIE like 'AR8%'
and RESULT = 'X'
and EXISTS(SELECT FRIE, RESULT
FROM [HOME].[dba].[ARCHIVE]
where RESULT = 'Y');
Everything as far as the EXISTS works but afterwards it just ignores the nested query
Your query doesn't have the same WHERE clause in the EXISTS portion. I think this will work for you:
SELECT *
FROM [HOME].[dba].[ARCHIVE]
WHERE FRIE like 'AR8%'
AND RESULT = 'X'
AMD EXISTS(SELECT TOP 1 1
FROM [HOME].[dba].[ARCHIVE]
where FRIE like 'AR8%' AND RESULT = 'Y');
I'd recommend using an INNER JOIN to a subquery rather than using an EXISTS statement. Something like this:
SELECT *
FROM [HOME].[dba].[ARCHIVE] a
INNER JOIN (SELECT FRIE
FROM [HOME].[dba].[ARCHIVE]
WHERE RESULT = 'Y') t1 ON a.FRIE = t1.FRIE
WHERE
FRIE like 'AR8%'
and RESULT = 'X'
That would return all rows from ARCHIVE where they there is a row with the same FRIE with a RESULT of X and a RESULT of Y.
Hopefully that helps.

SQL Server MAX and GROUP BY not playing nicely together

I have a T-SQL query of the form:
SELECT f.fizz_name, b.buzz_version, fu.foo_name
FROM fizz f
INNER JOIN buzz b
ON f.fizz_id = b.fizz_id
INNER JOIN foo fu
ON b.buzz_id = fu.buzz_id
WHERE f.bar LIKE 'YES'
When I run this query I get the following results:
fizz_name buzz_version foo_name
====================================
Gamma 0.3.960 Test
Gamma 0.3.961 Test
Gamma 0.3.960 Test
Gamma 0.3.961 Test
Delta 0.3.2588 Test
Delta 0.3.2589 Test
Delta 0.3.2588 Test
Delta 0.3.2589 Test
Echo 2.2.38 Test
Echo 2.2.38 Test
The problem with this is that it contains a lot of entries that I don't care about. In reality I only care about the largest buzz_version for each fizz instance, in other words:
fizz_name buzz_version foo_name
====================================
Gamma 0.3.961 Test
Delta 0.3.2589 Test
Echo 2.2.38 Test
...because "2.2.38" is the latest/lexiconographically-highest buzz_version for Echo, and same for the other fizzes.
So I am trying to use GROUP BY in concert with MAX to fetch these values like so:
SELECT f.fizz_name, MAX(b.buzz_version), fu.foo_name
FROM fizz f
INNER JOIN buzz b
ON f.fizz_id = b.fizz_id
INNER JOIN foo fu
ON b.buzz_id = fu.buzz_id
WHERE f.bar LIKE 'YES'
GROUP BY b.buzz_version
But that gives me an error:
Column 'fizz.fizz_name' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Where am I going wrong, and why?
You are grouping by the aggregate in your query. You need to group by the scalar columns instead. In this case, group by f.fizz_name, fu.foo_name
You want one result row per fizz_name, so you must group by fizz_name. You show MAX(b.buzz_version) with it and must decide which fu.foo_name to show. E.g.:
SELECT f.fizz_name, MAX(b.buzz_version), MAX(fu.foo_name)
FROM fizz f
INNER JOIN buzz b ON f.fizz_id = b.fizz_id
INNER JOIN foo fu ON b.buzz_id = fu.buzz_id
WHERE f.bar LIKE 'YES'
GROUP BY f.fizz_name;

Resources