Query to the get the Max value using Join in SQL Server - sql

I have a table of Users:
|Username|UserType|
|John |A |
|Mary |A |
|Anna |B |
and UserPoints
|UserType|MinPoints|Level |
|A |100 |Bronze |
|A |200 |Silver |
|A |300 |Gold |
|B |500 |Bronze |
and Useraddress
|UserType|Address
|A |Address1
|B |Address2
I am looking for a query to get the max value of MinPoints column.
I want the result without using Group by clause.
I tried the below
Select UserType,UA.Address
,(Select max(MinPoints) from Users T1 WHERE T1.Usertype=U.Usertype)MinPoints from Users U
Left Join UserAddress UA on UA.UserType=U.UserType
Select UserType,UA.Address,MinPoints
from Users U
Left Join UserAddress UA on UA.UserType=U.UserType
Left Join (Select UserType,max(MinPoints) from Users T1 Group by UserType) x ON X.Usertype=U.Usertype
For the above queries I got the same result.
But what I want is which is query is better keeping in view the performance.
Please suggesst

This will return all user data for the user or users whose MinPoints are equal to the maximum value of MinPoints. With the sample data, JOIN will work, but you may need them to be LEFT JOINs.
SELECT
u.UserName,
ua.Address,
up.MinPoints AS MaxOfMinPoints
FROM
UserPoints AS up
JOIN
Users AS u
ON u.UserType = up.UserType
JOIN
UserAddress AS ua
ON ua.UserType = up.UserType
WHERE
up.MinPoints = (SELECT MAX(s.MinPoints) FROM UserPoints AS s)

Related

Sum by groups between 2 tables

I, im trying to Sum by groups between 2 tables. Basically im trying to show only the Table 'Count' with each SUM() of Table 'MoneyMovements' group by 'Bank_code'. Is this possible?. I tryed with Left join (including the 'MoneyMovements'in 'Count'). but i dont understand how to separe the sum... Any suggestion?. Im using ACCESS 2007 in VB.NET
Table 'Count'
+----+--------------+
|Code|Bank |
+----+--------------+
|1 |MACRO |
+----+--------------+
|2 |Santender Rio |
+----+--------------+
|3 |Galicia |
+----+--------------+
Table 'MoneyMovements'
+-----+--------------+
|Money|Bank_code |
+-----+--------------+
|200 |1 |
+-----+--------------+
|300 |1 |
+-----+--------------+
|0 |2 |
+-----+--------------+
|500 |3 |
+-----+--------------+
|100 |3 |
+-----+--------------+
Response i Want:
+-----+--------------+
|Money|Bank |
+-----+--------------+
|500 |MACRO |
+-----+--------------+
|0 |Santender Rio |
+-----+--------------+
|600 |Galicia |
+-----+--------------+
You need join with group by like:
Select c.Code, sum(m.Money) as Money
From Count c
inner join MoneyMovements m on c.Code = m.Bank_code
group by c.Code
Use "Left join" to get all the "Count" rows and Nz() to display 0 when there are no transactions in an account:
Select c.Code, Nz(sum(m.Money),0) as Money
From Count c
LEFT JOIN MoneyMovements m on c.Code = m.Bank_code
group by c.Code
Access really didn't like the table name "Count" so I used Counts instead, this is what I did:
SELECT Counts.code, Nz(Sum(MoneyMovements.Money),0) AS SumOfMoney
FROM Counts LEFT JOIN MoneyMovements ON Counts.Code = MoneyMovements.bank_code
GROUP BY Counts.code;

Find number of male and female friends with SQL

I'm using Oracle (SQL*Plus) and I currently have the following tables:
USERS:
Id|Name|Gender
1 |A |M
2 |B |F
3 |C |M
4 |D |F
FRIENDS
Id1|ID2
1 |2
1 |3
2 |3
2 |4
2 |1
3 |1
3 |2
4 |2
How would I query,"For each user, find the number of male and female friends?"
I need an output that looks like this:
Id|Male Friends|Female Friends
1 |1 |1
2 |2 |1
3 |1 |1
4 |0 |1
I appreciate the help.
Make a query with two outer joins - one to male friends, and another one to female friends. Group by user ID:
SELECT u.Id, COUNT(m.Id) as MaleFriends, COUNT(f.Id) as FemaleFriends
FROM Users u
LEFT OUTER JOIN Friends ff ON u.Id=ff.Id1
LEFT OUTER JOIN Users m ON ff.Id2=m.Id AND m.Gender='M'
LEFT OUTER JOIN Users f ON ff.Id2=f.Id AND f.Gender='F'
GROUP BY u.Id
The reason the counts of m.Id and f.Id would be different is that when a row of FRIENDS joins to a male friend, f.Id would be NULL, and vice versa. COUNT skips NULL values, producing the counts that you need.

sql return categories ordered by blog post date

I've a Wordpress website with articles. A post can contain or more categories (table wp_terms). Now I want a query that returns a list of all term names, ORDERED BY the blogs article date. I have experimented with a SELECT in a SELECT query, but that doesn't work... How can I do it and return the categories ordered by the article date?
table wp_posts (as example):
|ID------|post_title------------------|post_date-|
|1 |Test title |2014-05-05|
|2 |Test title 2 |2014-04-01|
|3 |Last test title |2014-02-02|
|4 |Another blog item |2014-01-06|
table wp_terms:
|term_id|name---------|
|1 |computers |
|2 |home |
|3 |work |
table wp_term_relationships
|object_id|term_taxonomy_id|term_order|
|1 |2 | 0 |
|1 |1 | 0 |
|2 |3 | 0 |
table wp_term_taxonomy
|term_taxonomy_id | term_id |
|1 |1 |
|2 |2 |
|3 |3 |
|4 |4 |
This is my current query, but this doesn't work right...
SELECT t.*, p.* FROM wp_terms AS t
JOIN wp_term_taxonomy AS tt ON tt.term_id = t.term_id
JOIN wp_term_relationships AS tr ON tr.term_taxonomy_id = tr.term_taxonomy_id
LEFT JOIN ( SELECT `ID`, `post_title`, max(`post_date`) as `date` FROM wp_posts
GROUP BY `ID` ) as p on p.`ID`= tr.`object_id` GROUP BY t.`term_id` ORDER BY p.`date` desc
Still not sure what you are trying to achieve. But this is your query which runs without errors
SELECT t.*, p.*
FROM wp_terms AS t JOIN wp_terms_taxonomy AS tt
ON tt.term_id = t.term_id
JOIN wp_terms_relationship AS tr
ON tr.term_taxonomy_id
= tr.term_taxonomy_id LEFT JOIN
( SELECT ID, post_title, max(post_date) as date
FROM wp_posts
GROUP BY ID , post_title) as p on p.ID= tr.object_id
GROUP BY t.term_id,t.name,p.id,p.post_title,p.date
ORDER BY p.date desc
fiddle

SQL Server recursive query with associated table

I have a typical parent/child relationship table to represent folders. My challenge is using it in conjunction with another table.
The folder table is like this:
+--+----+--------+
|id|name|parentid|
+--+----+--------+
|1 |a |null |
+--+----+--------+
|2 |b |1 |
+--+----+--------+
|3 |c1 |2 |
+--+----+--------+
|4 |c2 |2 |
+--+----+--------+
The association table is like this:
+--+--------+
|id|folderid|
+--+--------+
|66|2 |
+--+--------+
|77|3 |
+--+--------+
so that where association.id = 66 has a relationship to folder.id = 2
What I need to do is find the association.id of the first ancestor with a record in the association table.. Using the example data above, given folder.id of 3 I expect to find 77; given folder.id of 2 or 4 I expect to find 66; any other folder.id value would find null.
Finding folder ancestry can be done with a common table expression like this:
WITH [recurse] (id,name,parentid,lvl) AS
(
select a.id,a.name,a.parentid,0 FROM folder AS a
WHERE a.id='4'
UNION ALL
select r.id,r.name,r.parentid,lvl+1 FROM folder as r
INNER JOIN [recurse] ON recurse.parentid = r.id
)
SELECT * from [recurse] ORDER BY lvl DESC
yielding the results:
+--+----+--------+---+
|id|name|parentid|lvl|
+--+----+--------+---+
|1 |a | |2 |
+--+----+--------+---+
|2 |b |1 |1 |
+--+----+--------+---+
|4 |c2 |2 |0 |
+--+----+--------+---+
To include the association.id I've tried using a LEFT JOIN in the recursive portion of the CTE, but this is not allowed by SQL Server.
What workaround do I have for this?
Or better yet, is the a way to query directly for the particular association.id? (e.g., without walking through the results of the CTE query that I have been attempting)
SELECT r.id, r.name, r.parentid, r.lvl, a.folderid, a.id as associationid
FROM [recurse] r
LEFT JOIN [association] a
ON r.id = a.folderid
WHERE a.folderId IS NOT NULL
ORDER BY lvl DESC
This will give you the records that have values in the association table. Then you could limit it to the first record that has a value or just grab the top result

Oracle SQL: Joining another table with one missing tuple

I have the following two tables, one stores order information, one stores key|value information.
There is no CD = D for key COLOR_CD. I would like to join both tables to get all orders irregardless of the key|value pair not found in the MASS_DECODE table.
Can i get some help please :D
ORDER_INFORMATION
ORDER_NUMBER |COLOR_CD |
----------------|-----------|
1 |A |
2 |B |
3 |C |
4 |D |
MASS_DECODE
KEY |CD |VALUE |
------------|---------------|-----------|
COLOR_CD |A |Green |
COLOR_CD |B |Blue |
COLOR_CD |C |Red |
SIZE_CD |A |Large |
SIZE_CD |B |Medium |
SIZE_CD |C |Small |
SQL:
select order_number, cd, value
from order_information
left outer join mass_decode
on (color_cd = cd)
and key = 'COLOR_CD';
Outcome:
ORDER_NUMBER |CD |VALUE |
----------------|-----------|-----------|
1 |A |Green |
2 |B |Blue |
3 |C |Red |
Expected:
ORDER_NUMBER |CD |VALUE |
----------------|-----------|-----------|
1 |A |Green |
2 |B |Blue |
3 |C |Red |
4 |D |NULL |
EDIT: I am sorry i have presented incorrect information for my tables. Since been corrected.
select *
from order_information oi
left join mass_decode md
on (
oi.color_cd = md.cd
and oi.key = md.key
)
where oi.key = 'KEY_A';
SQLFiddle
upd:
According to your updates:
select *
from order_information oi
left join mass_decode md
on oi.color_cd = md.cd
where md.key = 'COLOR_CD' or md.key is null;
SQLFiddle
Your column names are ambiguous. You have two columns named the same in two tables, so which column does the key in your where clause refer to? I think in later versions of Oracle, this will actually give you an error. Try this:
select oi.order_number, oi.color_cd, md.value
from order_infomation oi
left outer join mass_decode md
on (oi.color_cd = md.cd)
where oi.key = 'KEY_A';
Edit:
Based on your response to #billy, it sounds like that wasn't working for you. You could also try putting the key predicate into the join clause:
select oi.order_number, oi.color_cd, md.value
from order_infomation oi
left outer join mass_decode md
on (oi.color_cd = md.cd) and oi.key = 'KEY_A';
This should do :
SELECT
order_number,
color_cd AS cd,
(
SELECT value FROM mass_decode m2 WHERE m2.key = o.key AND m2.cd = o.color_cd
) AS value
FROM order_information o
WHERE o.key = 'KEY_A'