Inner join with Count in SQL and group by - sql-server

I have this table called Equipos.
id idType
1 1
3 2
4 3
5 4
6 4
And this other table which I want to Inner Join with (the catalogue with descriptions or ids).
id descripcion
1 Macbook
2 iMac
3 Dell Lap
4 Dell Lap OP
I want something like
descripcion count
Macbook 1
iMac 1
Dell Lap 1
Dell Lap OP 2
This is what Im trying so far.
select tipoId, count(tipoId)
from Equipos eq
group by tipoId
inner join TipoEquipo tip on tip.id=eq.idType
But to no avail.

This is indeed basic SQL, but I would prefer to use left outer join for this.
select tip.descripcion, count(eq.idType)
from TipoEquipo tip
left outer join Equipos eq on tip.id=eq.idType
group by tip.descripcion

This is basic sql, put join and group by in the right order and group by description not id.
select tip.descripcion, count(*) as count
from Equipos eq
inner join TipoEquipo tip on tip.id=eq.idType
group by tip.descripcion

Related

How to Left Inner Join two queries in Sybase?

I have two queries that should be joined together. Here is my query 1:
SELECT
t1.rec_id,
t1.category,
t1.name,
t1.code,
CASE
WHEN t1.name= 'A' THEN SUM(t1.amount)
WHEN t1.name = 'D' THEN SUM(t1.amount)
WHEN t1.name = 'H' THEN SUM(t1.amount)
WHEN t1.name = 'J' THEN SUM(t1.amount)
END AS Amount
FROM Table1 t1
GROUP BY t1.name, t1.rec_id, t1.category, t1.code
Query 1 produce this set of results:
Rec ID Category Name Code Amount
1 1 A MIX 70927.00
1 3 D MIX 19922.00
1 2 H MIX 55104.00
1 4 J MIX 76938.00
Then I have query 2:
SELECT
CASE
WHEN t2.category_id = 1 THEN SUM(t2.sum)
WHEN t2.category_id = 2 THEN SUM(t2.sum)
WHEN t2.category_id = 3 THEN SUM(t2.sum)
WHEN t2.category_id = 4 THEN SUM(t2.sum)
END AS TotalSum
FROM Table2 t2
INNER JOIN Table1 t1
ON t1.amnt_id = t2.amnt_id
AND t2.unique_id = #unique_id
GROUP BY t2.category_id
The result set of query 2 is this:
TotalSum
186013.00
47875.00
12136.00
974602.00
All I need is this result set that combines query 1 and query 2:
Rec ID Category Name Code Amount TotalSum
1 1 A MIX 70927.00 186013.00
1 3 D MIX 19922.00 47875.00
1 2 H MIX 55104.00 12136.00
1 4 J MIX 76938.00 974602.00
As you can see there is connection between table 1 and table 2. That connection is amnt_id. However, I tried doing LEFT INNER JOIN on query 1 and then simply using same logic with case statement to get the total sum for table 2. Unfortunately Sybase version that I use does not support Left Inner Join. I'm wondering if there is other way to join these two queries? Thank you
I wondered if the CASE statement makes sense in the first query because it sums in every row. Are there other values for the name column except A, D, H, J? If not you can change the CASE statement to SUM(t1.amount) AS Amount. Also the GROUP BY in the first query seems dubious to me: you are grouping by the record id column - that means you are not grouping at all but instead return every row. If that is what you really want you can omit the SUM at all and just return the pure amount column.
As far as I understood your problem and your data structure: the values in Table2 are kind of category sums and the values in Table1 are subsets. You would like to see the category sum for every category in Table1 next to the single amounts?
You would typically use a CTE (common table expression, "WITH clause") but ASE doesn't support CTEs, so we have to work with joins. I recreated your tables in my SQL Anywhere database and put together this example. In a nutshell: both queries are subqueries in an outer query and are left joined on the category id:
SELECT *
FROM
(
SELECT
t1.rec_id,
t1.category,
t1.name,
t1.code,
CASE
WHEN t1.name= 'A' THEN SUM(t1.amount)
WHEN t1.name = 'D' THEN SUM(t1.amount)
WHEN t1.name = 'H' THEN SUM(t1.amount)
WHEN t1.name = 'J' THEN SUM(t1.amount)
END AS Amount
FROM Table1 t1
GROUP BY t1.rec_id, t1.name, t1.category, t1.code
) AS t1
LEFT JOIN
(
SELECT category_id, SUM(sum) FROM
table2
GROUP BY category_id
) AS totals(category_id, total_sum)
ON totals.category_id = t1.category;
This query gives me:
Rec ID Category Name Code Amount Category_id total_sum
2 3 D MIX 19922.00 3 47875.00
3 2 H MIX 55104.00 2 12136.00
1 1 A MIX 70927.00 1 186013.00
4 4 J MIX 76938.00 4 974602.00
You surely have to tweak it a bit including your t2.unique_id column (that I don't understand from your queries) but this is a practical way to work around ASE's missing CTE feature.
BTW: it's either an INNER JOIN (only the corresponding records from both tables) or a LEFT (OUTER) JOIN (all from the left, only the corresponding records from the right table) but a LEFT INNER JOIN makes no sense.

SQL Join Including NULLs

Using SQL Server Management Studio 2016 (v 13.0).
I have two tables with two distinct keys I can use to join, with the catch being that there are mixed NULLs in both PK columns:
Table 1 Table 2
Acct1 App1 Acct2 App2 Product
----------- ----------------------
1 A NULL A Bed
2 B 2 B Sofa
3 C 3 NULL Bed
4 D 4 D Bed
Desired result in the joined table, only including those where Product = Bed:
Acct App Product
1 A Bed
3 C Bed
4 D Bed
Thank you!
While I agree #d219's answer should be the correct solution, a different approach could use an or in the join such like:
select Acct1,App1,Product
from table1 inner join table2
on App1=App2 or Acct1=Acct2
where Product='Bed'
See this post for discussion on using the or join.
One way would be to do two separate SELECT statements using each key and then UNION them, something like this:
SELECT t1.Acct1, t1.App1, t2.Product
FROM Table1 t1
INNER JOIN Table2 t2
ON t1.Acct1 = t2.Acct2
WHERE t2.Product = 'Bed'
UNION
SELECT t1.Acct1, t1.App1, t2.Product
FROM Table1 t1
INNER JOIN Table2 t2
ON t1.App1 = t2.App2
WHERE t2.Product = 'Bed'

how to sort according to special case in sql

I have this case
i have stored procedure get all persons as couples male and female
i want to sort those couple according to male name
i try some sing like that
SELECT P.GenderTypeID,
Couple.CoupleID,
P.PersonID ,
p.NameAr,
p.NameEn ,
p.Mobile
FROM tbl_Couples Couple
LEFT OUTER JOIN tbl_Persons P
ON P.CoupleID = Couple.CoupleID
ORDER BY
CASE WHEN P.GenderTypeID = 1
THEN '1'--Male
WHEN P.GenderTypeID = 2
THEN '2'--Female
ELSE P.GenderTypeID END ASC ,
p.NameAr
put it get male first then female
i get that
GenderTypeID CoupleID PersonID NameAr NameEn Mobile
1 3 10 أحمد Ali 01255678668
1 5 15 سمير Samier 01255353563
1 4 17 سيد Said 012359989744
2 5 14 سامية Samia 01156786868
2 4 16 سعاد Suadd 01353563563
2 3 12 منى Mona 010264646444
put i expect
GenderTypeID CoupleID PersonID NameAr NameEn Mobile
1 3 10 أحمد Ali 01255678668
2 3 12 منى Mona 010264646444
1 5 15 سمير Samier 01255353563
2 5 14 سامية Samia 01156786868
1 4 17 سيد Said 012359989744
2 4 16 سعاد Suadd 01353563563
Use a CTE to first select only the males, which you then join with the tbl_Couples and tbl_Persons tables, which will give a result set in which the male part of the couple is duplicated for the "males" CTE.
WITH tbl_MaleOnly
AS
(
SELECT *
FROM tbl_Persons
WHERE GenderTypeID = 1
)
SELECT P.GenderTypeID,
Couple.CoupleID,
P.PersonID ,
p.NameAr,
p.NameEn ,
p.Mobile
FROM tbl_MaleOnly Male
LEFT OUTER JOIN tbl_Couples Couple
ON Couple.CoupleID = Male.CoupleID
LEFT OUTER JOIN tbl_Persons P
ON P.CoupleID = Couple.CoupleID
ORDER BY Male.NameAr
, P.GenderTypeID
Instead of a CTE, you could also use an inline view: replace "tbl_MaleOnly" in the main select with the CTE select in parenthesis.
You don't need to use any case statement in your order by clause, Just use this
SELECT P.GenderTypeID,
Couple.CoupleID,
P.PersonID ,
p.NameAr,
p.NameEn ,
p.Mobile
FROM tbl_Couples Couple
LEFT OUTER JOIN tbl_Persons P
ON P.CoupleID = Couple.CoupleID
ORDER BY P.GenderTypeID, p.NameAr
Or if you want to order your record by CoupleID just change the order by
ORDER BY Couple.CoupleID, p.NameAr

How to Improve "having sum" query

I have this query:
Select
DescFornecedor, DescUsuario, Classificacao,
Sum(Tempo) as Tempo,
Case Classificacao
When 'Agendamento' Then 2
When 'Aguardando cadastro' Then 3
When 'Descarte' Then 8
When 'Desistência' Then 7
When 'Em Pausa' Then 4
When 'Em Volta' Then 10
When 'Entrevista' Then 1
When 'Filtro' Then 5
When 'Outros' Then 9
When 'Recusa' Then 6
When 'Sem Atividade' Then 11
End as Ordem
from
vwProducaoGeralTempoLogadoSemAtividade t1 With(NoLock)
Where
Not Exists (Select 0
from vwProducaoGeralTempoLogadoSemAtividade t2 With(NoLock)
Where T1.CodUsuario = t2.CodUsuario
Group by CodUsuario
Having Sum(tempo) <> MAx(tempoLogado))
Group By
DescFornecedor, DescUsuario, Classificacao
When we use it, it returns the results in 30~1min.
Now I've made some adjustments:
Select DescFornecedor,DescUsuario,Classificacao,Sum(t1.Tempo) as Tempo,
Case Classificacao
When 'Agendamento' Then 2
When 'Aguardando cadastro' Then 3
When 'Descarte' Then 8
When 'Desistência' Then 7
When 'Em Pausa' Then 4
When 'Em Volta' Then 10
When 'Entrevista' Then 1
When 'Filtro' Then 5
When 'Outros' Then 9
When 'Recusa' Then 6
When 'Sem Atividade' Then 11
End as Ordem
from vwProducaoGeralTempoLogadoSemAtividade t1 With(NoLock)
inner join (
select CodUsuario, SUM(tempo) as Tempo, MAX(tempologado) as TempoLogado
from vwProducaoGeralTempoLogadoSemAtividade with(nolock)
group by CodUsuario
) t2
on t1.CodUsuario = t2.CodUsuario and
t2.Tempo = t2.TempoLogado
Group By DescFornecedor,DescUsuario,Classificacao
But i's stil slow ! lasting 10~20secs.
How can i improve this query?
i'm out of ideas.
don't know what to do with the time comparison.
Thank you very much.
( Indexes and stats are ok, not even the trace can help me now )
If there's no typo in the second query, I have a problem with this part:
...on ... and t2.Tempo = t2.TempoLogado
The second criteria is based upon only t2, so can be removed from the join criteria and be handled inside t2, by adding:
...having SUM(tempo) = MAX(tempologado)
I'm not sure if it makes much improvement, though.
UPDATE: Since CodUsuario is a computed column in a view, the solution is to alter the view to be an indexed view and then create an index.
create index CodUsuario on vwProducaoGeralTempoLogadoSemAtividade(CodUsuario)
try cross apply
cross apply (
select CodUsuario, SUM(tempo) as Tempo, MAX(tempologado) as TempoLogado
from vwProducaoGeralTempoLogadoSemAtividade with(nolock)
group by CodUsuario
) t2
where t1.CodUsuario = t2.CodUsuario and
t2.Tempo = t2.TempoLogado
Group By DescFornecedor,DescUsuario,Classificacao

how to group in two tables in SQl server?

I have the following issue :
table # 1 structure :
Requests table for example have 2 columns :
Request_ID Branch_Name
1 xx
2 yy
3 xx
4 xx
5 yy
The second table : Requests_Items for example have the following columns
Request_ID Price
1 100
1 30
1 450
2 10
2 18
So i want my result set to be like :
Branch Name Num_of_Requests Total_Price
xx 3 580
Can you please help
select r.Branch_Name,
count(r.request_id) as Num_of_Requests,
sum(i.price) as Total_Price
from Requests r
left join Requests_Items i on i.Request_ID = r.Request_ID
group by r.Branch_Name
jurgen d was almost there
select r.Request_Id, r.Branch_Name,
COUNT(i.Price) as [Number of Requests],
SUM(i.Price) as [Total]
from Requests r
left join Requests_Items i
on r.Request_Id = i.Request_Id
group by r.Request_Id, r.Branch_Name
select r.Branch_Name, COUNT(ri.Request_ID) as Num_of_Requests, SUM(ri.Price) as Total_Price
from dbo.Requests r
left join dbo.Requests_Items ri
on r.Request_ID = ri.Request_ID
group by r.Branch_Name
Let this is my [Employees] Table
Here is my Dept table
I want the output like this using join and group by
So here is the Query for this-
select max(e.salary) as maxsalary,d.Dept from Employees e inner join DEpt d on e.DeptId=d.id group by e.DeptId,d.Dept
enter code here

Resources