SQL join count and select query - sql

I have two tables, one is a list of 'gangs' and one is a list of 'gang_members' the gang_members.gang_id refers to the gang.id they are in, I know how to count all the members in one gang, but I need to join the following queries into one:
SELECT * FROM gangs LIMIT 8
SELECT count(gang_id) FROM gangs_members WHERE gang_id = <GANG ID>
I think this is possible, I could do it in a loop while it's going through the gangs but that would be inefficient

SELECT A.*, B.RC
FROM gangs A
LEFT JOIN (SELECT gang_id, COUNT(*) AS RC FROM gangs_members GROUP BY gang_id) B ON A.gang_id=B.gang_id

Probably something like this
SELECT count(gang_id)
FROM gangs_members
WHERE gang_id IN (SELECT gang_id FROM gangs LIMIT 8)

Related

Comparing two sum function in where clause

I want to check that an amount of likes the users received in all their personal pictures is at least twice as large as the number of likes received in the group pictures in which they are tagged.
In case the user is not tagged in any group photo but is tagged in a personal picture that has received at least one like, it will be returned.
My Question is:
How can I make a comparison between 2 sum functions
Where one result of the sum is returned in the nested query and compared with the external query.
Can I set an auxiliary variable to enter the sum value in it and compare it?
Thanks for the helpers:)
Select distinct UIP.userID
From tblUserInPersonalPic UIP
where **sum(UIP.numOfLikes) over (Partition by UIP.userID)*0.5** >
(Select distinct U.userID, sum(P.numOfLikes) over (Partition by U.userID)
From tblgroupPictures P left outer join
tblUserInGroupPic U On P.picNum=U.picNum
group by U.userID,P.numOfLikes,P.picNum)
It's kinda hard to know for sure, and of course I can't test my answer,
but I think you can do it with a couple of left joins, group by and having:
SELECT Personal.UserId
FROM tblUserInPersonalPic Personal
LEFT JOIN tblUserInGroupPic UserInGroup ON Personal.userID = UserInGroup.UesrId
LEFT JOIM tblgroupPictures GroupPictures ON UserInGroup.picNum = GroupPictures.picNum
GROUP BY Personal.userID
HAVING SUM(GroupPictures.numOfLikes) * 2 < SUM(Personal.numOfLikes)
Please note: When posting sql questions it's always best to provide sample data as DDL + DML (Create table + insert into statements) and desired results, so that who ever answers you can test the answer before posting it.
Try using two ctes..pseudo code.Also note distinct in second query will not even work,since you are returning two columns,so i changed it it below,so that you can get that column as well
;with tbl1
as
(
select a,sum(col1) as summ
from
tbl1
)
,tbl2
as
(
select userid,sum(Anothersmcol) as sum2
from tbl2
)
select tbl1.columns,tbl2.columns
from
tbl1 t1
join
tbl2 t2
on t1.sumcol>t2.sumcol
You can't use window functions in a where clause. Define it in a subquery:
select *
from (
select sum(...) over (...) as Sum1
, OtherColumn
from YourTable
) sub
where Sum1 < (...your subquery...)

Join and compare 2 queries of 2 tables

This is probably a quite trivial question for many here but I am not used to write sub queries and joins, so I hope someone want to help.
I have two tables: new_road and old_roads.
These two queries sum up the length of the roads belonging to a specific road number.
SELECT new_road.nummer, SUM(new_road.length) FROM road_table.road GROUP BY new_road.nummer
SELECT old_road.nummer, SUM(ST_length(old_road.geom)) FROM old_road_table.old_road GROUP BY old_road.nummer
I wish to have a result table where these two queries are joined so I can compare the new and old summed length for each road number.
Like
old.nummer old.length new.nummer new.lenght
2345 10.3 2345 10.5
2346 578.2 2346 600
2347 54.2 NULL NULL
NULL NULL 2546 32.2
I think some version of an outer join is needed because there will be a road numbers in the old_road table that does not exist in the new.road table and i would like to see them too.
Appreciate any advice
Edit:
After advice from below did I came up with this:
SELECT * FROM
(SELECT new_road.nummer, SUM(new_road.length) FROM road_table.road GROUP BY new_road.nummer) new_table
FULL OUTER JOIN
(SELECT old_road.nummer, SUM(ST_length(old_road.geom)) FROM old_road_table.old_road GROUP BY old_road.nummer) old_table
ON new_road.nummer = old_road.nummer
But each time I run it I get missing FROM-clause entry. When I run each sub query individually they work. I have crosschecked with the documentation and it look OK to me, but clearly I am missing something here.
Consider using a FULL OUTER JOIN
This is not the exact output you requested but you don't need to display the nummer twice.
SELECT
COALESCE(new_road.nummer,old_road.nummer)nummer,
new_road.length,
old_road.length
FROM (
SELECT new_road.nummer
,SUM(new_road.length) length
FROM road_table.road
GROUP BY new_road.nummer
) new_road
FULL OUTER JOIN (
SELECT old_road.nummer
,SUM(ST_length(old_road.geom))length
FROM old_road_table.old_road
GROUP BY old_road.nummer
) old_road ON
old_road.nummer = new_road.nummer
Following query should solve the purpose. I didn't run it but the basic idea is result of a query on a table is another table on which you can query again.
Select * FROM (SELECT new_road.nummer, SUM(new_road.length) FROM road_table.road GROUP BY new_road.nummer) table1 JOIN (SELECT old_road.nummer, SUM(ST_length(old_road.geom)) FROM old_road_table.old_road GROUP BY old_road.nummer) table2 ON table1.new_road.nummer = table2.old_road.nummer
The tricky bit here is that you want to make sure you include all of the keys from both lists. My favorite way to do this kind of thing is:
select * from (
SELECT distinct new_road.nummer as nummer from road_table.road
union
SELECT distinct old_road.nummer as nummer FROM old_road_table.old_road
) allkeys
left join
(
SELECT new_road.nummer as nummer, SUM(new_road.length) as nlen
FROM road_table.road GROUP BY new_road.nummer
) n
on allkeys.nummer = n.nummer
left join
(
SELECT old_road.nummer as nummer, SUM(ST_length(old_road.geom)) as olen
FROM old_road_table.old_road GROUP BY old_road.nummer
) o
on allkeys.nummer = o.nummer
The first subquery builds a list of all keys, then you join to both of your queries from there. There's nothing wrong with an outer join, but I find this easier to manage if you have to include 3 or more tables. If you had to include another table it would just be one more union in allkeys and one more left join to that table.

SQL SERVER Join 2 tables with COUNT(*)

I need some help to join my tables, I used 2 tables
//table news
id_news|title|
1 |first..|
2 |second..|
//table comment
id_comment|content|id_news
1|Haha..|1
2|Hahe..|2
3|Hoho..|1
I need an output use COUNT(*) comments in id_news 1
like
id_news|title|total_comment|
1|first..|**2**|
so far my syntax like
SELECT
news.id_news,
COUNT(distinct comment.id_news)
FROM
news
inner join comment ON (comment.id_news=news.id_news)
group by
news.id_news
I think you want:
SELECT news.id_news, COUNT(*)
FROM news INNER JOIN
comment
ON comment.id_news = news.id_news
GROUP BY news.id_news;
Note the following:
The select clause uses the same column as the group by
The COUNT() is not using a distinct. In your formulation, it would always return 1, regardless of the number of comments.
If you want news items with no comments, you would use a left outer join and change the count(*) to count(comment.id_news).
Try This Query you will get the data as you want :
SELECT
news.id_news,news.title,
(select count(*) from comment group_by id_news) as total_comment
FROM
news
inner join comment ON comment.id_news=news.id_news

Self Join bringing too many records

I have this query to express a set of business rules.
To get the information I need, I tried joining the table on itself but that brings back many more records than are actually in the table. Below is the query I've tried. What am I doing wrong?
SELECT DISTINCT a.rep_id, a.rep_name, count(*) AS 'Single Practitioner'
FROM [SE_Violation_Detection] a inner join [SE_Violation_Detection] b
ON a.rep_id = b.rep_id and a.hcp_cid = b.hcp_cid
group by a.rep_id, a.rep_name
having count(*) >= 2
You can accomplish this with the having clause:
select a, b, count(*) c
from etc
group by a, b
having count(*) >= some number
I figured out a simpler way to get the information I need for one of the queries. The one above is still wrong.
--Rep violation for different HCP more than 5 times
select distinct rep_id,rep_name,count(distinct hcp_cid)
AS 'Multiple Practitioners'
from dbo.SE_Violation_Detection
group by rep_id,rep_name
having count(distinct hcp_cid)>4
order by count(distinct hcp_cid)

Getting difference of two counts in SQL

I'm doing some QA in Netezza and I need to compare the counts from two separate SQL statements. This is the SQL that I am currently using
SELECT COUNT(*) AS RECORD_COUNT
FROM db..EXT_ACXIOM_WUL_FILE A
LEFT JOIN (select distinct CURRENTLY_OPTED_IN_FL,mid_key from db..F_EMAIL) B
ON A.MID_KEY=B.MID_KEY
MINUS
SELECT COUNT(*)
FROM db..EXT_ACXIOM_WUL_FILE A
However, it seems like MINUS doesn't work like that. When the counts match, instead of returning 0, this will return null for Record_count. I basically the record count to be computed as:
record_count=count1-count2
So it is 0 if the counts are equal or the difference otherwise. What is the correct SQL for this?
SELECT
(
SELECT COUNT(*) AS RECORD_COUNT
FROM db..EXT_ACXIOM_WUL_FILE A
LEFT JOIN (select distinct CURRENTLY_OPTED_IN_FL,mid_key from db..F_EMAIL) B
ON A.MID_KEY=B.MID_KEY
) -
(
SELECT COUNT(*)
FROM db..EXT_ACXIOM_WUL_FILE A
) TotalCount
Oracle's MINUS (EXCEPT in SQL Server) is a whole different animal :)
If you understand UNION and then think sets, you will understand MINUS / EXCEPT
MINUS is set difference, not for arithmetic operations.
You could do
SELECT COUNT(*) - (SELECT COUNT(*)
FROM db..EXT_ACXIOM_WUL_FILE A) AS Val
FROM db..EXT_ACXIOM_WUL_FILE A
LEFT JOIN (select distinct CURRENTLY_OPTED_IN_FL,
mid_key
from db..F_EMAIL) B
ON A.MID_KEY = B.MID_KEY
Or another option
SELECT COUNT(*) - COUNT(DISTINCT A.PrimaryKey) AS Val
FROM db..EXT_ACXIOM_WUL_FILE A
LEFT JOIN (select distinct CURRENTLY_OPTED_IN_FL,
mid_key
from db..F_EMAIL) B
ON A.MID_KEY = B.MID_KEY
I think this may be what you are looking for
SELECT COUNT(distinct(CURRENTLY_OPTED_IN_FL + F_EMAIL.MID_KEY)) - count(distinct(EXT_ACXIOM_WUL_FILE.MID_KEY))
FROM EXT_ACXIOM_WUL_FILE
LEFT OUTER JOIN F_EMAIL
ON JOIN F_EMAIL.MID_KEY = EXT_ACXIOM_WUL_FILE.MID_KEY