These are my tables:
table BUSINESS
BUSINESSUSERNAME|BUSINESSPASSWORD|BUSINESSNAME|
Res1 |123 |Cafe |
Res2 |456 |Foodtruck |
table USER
USERNAME|USERPASSWORD|NAME|
user1 |123 |mr.1|
user2 |234 |mr.2|
table FOOD
FOODID|FOODNAME|FOODPRICE|BUSINESSUSERNAME|
1 |CAKE | 5 |Res1 |
2 |SHAKE | 2 |Res2 |
3 |COLA | 3 |Res1 |
table FOOD_RATING
FOODREVIEWID|FOODID|FOODRATING|BUSINESSUSERNAME|USERNAME|
1 |2 |3 |Res2 |user1 |
2 |2 |5 |Res2 |user2 |
3 |1 |4 |Res1 |user1 |
4 |3 |1 |Res1 |user1 |
I would like to get the top 10 foods based on average rating:
RANK|FOODNAME|FODPRICE|AVGRATING|BUSINESSUSERNAME
1 |CAKE |5 |4 |Res1
2 |SHAKE |3 |4 |Res2
3 |COLA |3 |1 |Res1
.
.
.
10
EDIT: Added SELECT TOP 10
The ORDER BY comes after GROUP BY
SELECT TOP 10 FOOD.FOODNAME, FOOD.FOODPRICE
, IIF(Round(Avg(FOODRATING), 1) IS NULL, 0, Round(Avg(FOODRATING), 1)) AS FOODAVGRATING
FROM FOOD
LEFT JOIN FOOD_REVIEW ON FOOD.FOODID = FOOD_REVIEW.FOODID
WHERE (((FOOD.BUSINESSUSERNAME) = "someusername"))
GROUP BY FOOD.FOODNAME, FOOD.FOODPRICE
ORDER BY IIF(Round(Avg(FOODRATING), 1) IS NULL, 0, Round(Avg(FOODRATING), 1)) DESC;
Related
I want to know the number of goals scored away and at home for each team in each season
season |home_goal |away_goal |team_home |team_away|
-----------------------------------------------------
1 | 1 |0 |France |Spain |
1 | 1 |2 |Italie |Spain |
1 | 0 |1 |Spain |Italie |
1 | 1 |3 |France |Italie |
1 | 1 |4 |Spain |Portugal |
1 | 3 |4 |Portugal |Italie |
2 | 1 |2 |France |Portugal |
2 | 1 |0 |Spain |Italie |
2 | 0 |1 |Spain |Portugal |
2 | 3 |2 |Italie |Spain |
2 | 0 |1 |France |Portugal |
... | ... |... |... |... |
I want this output
season |hg |ag |team |
-------------------------------------------
1 | 2 |0 |France |
1 | 1 |8 |Italie |
1 | 1 |2 |Spain |
1 | 3 |4 |Portugal |
2 | 1 |0 |France |
... | ... |... |... |
I don't have the expected result, I only have the goals scored at home...
WITH all_match AS (SELECT
season,
match.team_home AS ht,
match.home_goal AS hg
FROM
match
UNION ALL
SELECT
season,
match.team_away AS ta,
match.away_goal AS ag
FROM
match)
SELECT
season,
ht,
SUM(hg)
FROM
all_match
group by 1,2
Use below approach
select * from (
select season, 'home' location, team_home as team, home_goal as goal
from your_table
union all
select season, 'away' location, team_away as team, away_goal as goal
from your_table
)
pivot (sum(goal) for location in ('home', 'away'))
if applied to sample data in your question - output is
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 9 months ago.
Improve this question
This is only sample case, my original table is more complex.
Table A
| SchoolId| ClubId | ChildID|TeacherId|AttendanceDate|IsPresent|
|:------- |:------:| :-----:|:-------:|:------------:|:-------:|
| A | 1 | 1 |1 |22-MAY-2022 |1 |
| A | 1 | 2 |1 |22-MAY-2022 |0 |
| A | 1 | 3 |1 |22-MAY-2022 |1 |
| B | 2 | 11 |2 |22-MAY-2022 |1 |
| B | 2 | 22 |2 |22-MAY-2022 |0 |
| B | 2 | 33 |2 |22-MAY-2022 |0 |
Table B
|ChildID|TeacherId |CreateOn |IsPresent|ReasonId |
|:-----:|:-------: |:--------------:|:-------:|:-------:|
|2 |1 |22-MAY-2022 |0 |1 |
|2 |1 |23-MAY-2022 |0 |2 |
|22 |2 |22-MAY-2022 |0 |2 |
|33 |2 |22-MAY-2022 |0 |3 |
Table C
| ReasonId | ReasonMaster |
| -------- | -------------- |
| 1 | Health |
| 2 | Social |
| 3 | Unknown |
I want the left join result like this :
| SchoolId| ClubId | ChildID|TeacherId|AttendanceDate|IsPresent|ReasonId |ReasonMaster |
|:------- |:------:| :-----:|:-------:|:------------:|:-------:|:-------:|:------------:
| A | 1 | 1 |1 |22-MAY-2022 |1 | | |
| A | 1 | 2 |1 |22-MAY-2022 |0 |2 |Social |
| A | 1 | 3 |1 |22-MAY-2022 |1 | | |
| B | 2 | 11 |2 |22-MAY-2022 |1 | | |
| B | 2 | 22 |2 |22-MAY-2022 |0 |2 |Social |
| B | 2 | 33 |2 |22-MAY-2022 |0 |3 |Unknown |
Here are my cases:
I only want to retrieve the latest data from table B based on create on column on the table B to the table A. Because there is a duplicate input by users. for instance in the table B child Id= 2 & Teacher Id=1.
I only need to retrieve the the data if the status in the table A, column IsPresent=0
There is an additional data from table C which reason master.
Try this
Assuming MS SQL Server
--step 1 - Get the latest rec from table B
;with MaxCreate as ( Select ChildID,TeacherID,Max(CreateOn) as MaxCreateOn
from TableB
group by ChildID,TeacherID)
,LatestCreate as (select TableB.ChildID, TableB.TeacherId, TableB.CreateOn, TableB.IsPresent, TableB.ReasonId
from TableB
inner join MaxCreate
on TableB.ChildID = MaxCreate.ChildID
and TableB.TeacherId = MaxCreate.TeacherId
and TableB.CreateOn = MaxCreate.MaxCreateOn)
-- Now Join the latest to the other tables
Select
TableA.SchoolId
,TableA.ClubId
,TableA.ChildID
,TableA.TeacherId
,TableA.AttendanceDate
,TableA.IsPresent
,LatestCreate.ReasonId
,TableC.ReasonMaster
From
TableA Left join LatestCreate
on TableA.ChildID = LatestCreate.ChildID
and TableA.TeacherID = LatestCreate.TeacherID
left join TableC
on LatestCreate.ReasonId = TableC.ReasonId
Non CTE method
Select
TableA.SchoolId
,TableA.ClubId
,TableA.ChildID
,TableA.TeacherId
,TableA.AttendanceDate
,TableA.IsPresent
,LatestCreate.ReasonId
,TableC.ReasonMaster
From
TableB
inner join
( Select ChildID,TeacherID,Max(CreateOn) as MaxCreateOn
from TableB
group by ChildID,TeacherID) as MaxCreate
on TableB.ChildID = MaxCreate.ChildID
and TableB.TeacherId = MaxCreate.TeacherId
and TableB.CreateOn = MaxCreate.MaxCreateOn
Left join TableA
on TableA.ChildID = TableB.ChildID
and TableA.TeacherID = TableB.TeacherID
left join TableC
on TableB.ReasonId = TableC.ReasonId
I have a data set with 4 columns and want to count the number of times that the value in column 2 was equal to the value in one of the rows in column 0 and also the number of times that the value in column 3 was equal to the value in one of the rows in column 0. Also I want to filter the data based on the value in column 1.
Here is an example:
|0 |1 |2 |3 |
-----------------------------------------
|a |post |b |c |
|x |share |a |d |
|b |post |a |l |
|d |post |N/A |a |
-----------------------------------------
the result should look like this:
|0 |1 |2 |3 |4 |5 |
-------------------------------------------------------------
|a |post |b |c |2 |1 |
|b |post |a |l |1 |0 |
|d |post |N/A |a |0 |1 |
-------------------------------------------------------------
Therefore I need to add two columns to my data set. My initial thought is that I can use nested query. Here's my code:
SELECT *
FROM
(
select t.*,
(select count(*) from
(
select t.*,
(select count(*) from tab where [2] = t.[0]) [4]
from tab t
)
where [3] = t.[0]) [5]
from tab t
)
WHERE [1] = 'post'
but the the result of my query does not return column 4. Can you help me figure out the problem with my code?
Your query contains almost the correct code:
select
t.*,
(select count(*) from tab where [2] = t.[0]) [4],
(select count(*) from tab where [3] = t.[0]) [5]
from tab t
where t.[1] = 'post'
See the demo.
Results:
| 0 | 1 | 2 | 3 | 4 | 5 |
| --- | ---- | --- | --- | --- | --- |
| a | post | b | c | 2 | 1 |
| b | post | a | l | 1 | 0 |
| d | post | N/A | a | 0 | 1 |
i've got table like this.
|DateID |DivisionCode | TransactionIn| TransactionOut| OutstandingTransaction|
-----------------------------------------------------------------------------------
|2016-01-01 |ENP | 10 | 10 | 0 |
|2016-08-01 |PA | 2 | 0 | 2 |
|2016-08-08 |MD | 3 | 3 | 0 |
I use this to get total TransactionIn, TransactionOut, and OutstandingTransaction for each month.
;WITH MissingMonths
AS
(
SELECT number
FROM master..spt_values
WHERE number > 0 AND number < 13
GROUP BY number
),
RPT_POApproval
AS (
SELECT
MONTH(RPT.DateID) as DateID,
SUM(RPT.TransactionIn) as TransactionIn,
SUM(RPT.TransactionOut) as TransactionOut,
SUM(RPT.OutstandingTransaction) as OutstandingTransaction
FROM RPT_SummaryPOApproval RPT
WHERE RPT.Deleted = 0
GROUP BY MONTH(DateID)
)
SELECT COALESCE(number,DateID) AS Month
,COALESCE(TransactionIn, 0) AS TransactionIn
,COALESCE(TransactionOut, 0) AS TransactionOut
,COALESCE(OutstandingTransaction, 0) AS OutstandingTransaction
FROM MissingMonths MM
LEFT JOIN RPT_POApproval R ON MM.number = R.DateID
So it looks like this
|Month | TransactionIn| TransactionOut| OutstandingTransaction|
-------------------------------------------------------------------
|1 | 12 | 10 | 2 |
|2 | 0 | 0 | 0 |
|3 | 0 | 0 | 0 |
|4 | 0 | 0 | 0 |
|5 | 0 | 0 | 0 |
|6 | 0 | 0 | 0 |
|7 | 0 | 0 | 0 |
|8 | 3 | 3 | 0 |
|9 | 0 | 0 | 0 |
|10 | 0 | 0 | 0 |
|11 | 0 | 0 | 0 |
|12 | 0 | 0 | 0 |
How can I get the result using pivot so the data will look like this ?
|1 |2 |3 |4 |5 |6 |7 |8 |9 |10 |11 |12 |
-----------------------------------------
|12|0 |0 |0 |0 |0 |0 |3 |0 |0 |0 |0 | >> It's for Transaction In
|10|0 |0 |0 |0 |0 |0 |3 |0 |0 |0 |0 | >> It's for Transaction Out
|2 |0 |0 |0 |0 |0 |0 |3 |0 |0 |0 |0 | >> It's for Outstanding Trans
First UNPIVOT then PIVOT :)
;WITH cte AS (
SELECT COALESCE(number,DateID) AS Month
,COALESCE(TransactionIn, 0) AS TransactionIn
,COALESCE(TransactionOut, 0) AS TransactionOut
,COALESCE(OutstandingTransaction, 0) AS OutstandingTransaction
FROM MissingMonths MM
LEFT JOIN RPT_POApproval R ON MM.number = R.DateID
)
SELECT *
FROM (
SELECT [Month], [Transactions], [Values]
FROM (
SELECT *
FROM cte
) as p
UNPIVOT (
[Values] FOR [Transactions] IN (TransactionIn, TransactionOut, OutstandingTransaction)
) as unpvt
) as k
PIVOT (
MAX([Values]) FOR [Month] IN ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12])
) as pvt
Output:
Transactions 1 2 3 4 5 6 7 8 9 10 11 12
TransactionIn 12 0 0 0 0 0 0 3 0 0 0 0
TransactionOut 10 0 0 0 0 0 0 3 0 0 0 0
OutstandingTransaction 2 0 0 0 0 0 0 0 0 0 0 0
I am using SQL Server 2008 R2. I am having a database table like below :
+--+-----+---+---------+--------+----------+-----------------------+
|Id|Total|New|Completed|Assigned|Unassigned|CreatedDtUTC |
+--+-----+---+---------+--------+----------+-----------------------+
|1 |29 |1 |5 |6 |5 |2014-01-07 06:00:00.000|
+--+-----+---+---------+--------+----------+-----------------------+
|2 |29 |1 |5 |6 |5 |2014-01-07 06:00:00.000|
+--+-----+---+---------+--------+----------+-----------------------+
|3 |29 |1 |5 |6 |5 |2014-01-07 06:00:00.000|
+--+-----+---+---------+--------+----------+-----------------------+
|4 |30 |1 |3 |2 |3 |2014-01-08 06:00:00.000|
+--+-----+---+---------+--------+----------+-----------------------+
|5 |30 |0 |3 |4 |3 |2014-01-09 06:00:00.000|
+--+-----+---+---------+--------+----------+-----------------------+
|6 |30 |0 |0 |0 |0 |2014-01-10 06:00:00.000|
+--+-----+---+---------+--------+----------+-----------------------+
|7 |30 |0 |0 |0 |0 |2014-01-11 06:00:00.000|
+--+-----+---+---------+--------+----------+-----------------------+
Now, I am facing a strange problem while grouping the records by CreatedDtUTC column.
I want the distinct records from this table. Here you can observe that the first three records are duplicates created at the same date time. I want the distinct records so I had ran the query given below :
SELECT Id, Total, New, Completed, Assigned, Unassigned, MAX(CreatedDtUTC)
FROM TblUsage
GROUP BY CreatedDtUTC
But it gives me error :
Column 'TblUsage.Id' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
I also have tried DISTINCT for CreatedDtUTC column, but had given the same error. Can anyone let me know how to get rid of this?
P.S. I want the CreatedDtUTC coumn in CONVERT(VARCHAR(10), CreatedDtUTC,101) format.
Try this............
SELECT min(Id) Id, Total, New, Completed, Assigned, Unassigned, CreatedDtUTC
FROM TblUsage
GROUP BY Total, New, Completed, Assigned, Unassigned, CreatedDtUTC
The error message itself is very explicit. You can't put a column without applying an aggregate function to it into SELECT clause if it's not a part of GROUP BY. And the reason behind is very simple SQL Server doesn't know which value for that column within a group you want to select. It's not deterministic and therefore prohibited.
You can either put all the columns besides Id in GROUP BY and use MIN() or MAX() on Id or you can leverage windowing function ROW_NUMBER() in the following way
SELECT Id, Total, New, Completed, Assigned, Unassigned, CONVERT(VARCHAR(10), CreatedDtUTC,101) CreatedDtUTC
FROM
(
SELECT t.*, ROW_NUMBER() OVER (PARTITION BY Total, New, Completed, Assigned, Unassigned, CreatedDtUTC
ORDER BY id DESC) rnum
FROM TblUsage t
) q
WHERE rnum = 1
Output:
| ID | TOTAL | NEW | COMPLETED | ASSIGNED | UNASSIGNED | CREATEDDTUTC |
|----|-------|-----|-----------|----------|------------|--------------|
| 3 | 29 | 1 | 5 | 6 | 5 | 01/07/2014 |
| 6 | 30 | 0 | 0 | 0 | 0 | 01/10/2014 |
| 7 | 30 | 0 | 0 | 0 | 0 | 01/11/2014 |
| 5 | 30 | 0 | 3 | 4 | 3 | 01/09/2014 |
| 4 | 30 | 1 | 3 | 2 | 3 | 01/08/2014 |
Here is SQLFiddle demo
Try this:
SELECT MIN(Id) AS Id, Total, New, Completed, Assigned, Unassigned,
CONVERT(VARCHAR(10), CreatedDtUTC, 101) AS CreatedDtUTC
FROM TblUsage
GROUP BY Total, New, Completed, Assigned, Unassigned, CreatedDtUTC
Check the SQL FIDDLE DEMO
OUTPUT
| ID | TOTAL | NEW | COMPLETED | ASSIGNED | UNASSIGNED | CREATEDDTUTC |
|----|-------|-----|-----------|----------|------------|--------------|
| 1 | 29 | 1 | 5 | 6 | 5 | 01/07/2014 |
| 4 | 30 | 1 | 3 | 2 | 3 | 01/08/2014 |
| 5 | 30 | 0 | 3 | 4 | 3 | 01/09/2014 |
| 6 | 30 | 0 | 0 | 0 | 0 | 01/10/2014 |
| 7 | 30 | 0 | 0 | 0 | 0 | 01/11/2014 |