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 |
Related
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'm using postgre sql and i want to select data from database like this
------------------------------------
total1 | total2 | total3 | province|
------------------------------------
1 |1 |2 |Maluku |
2 |3 |4 |Aceh |
4 |7 |2 |Riau |
------------------------------------
but my result from query like this
------------------------------------
total1 | total2 | total3 | province|
------------------------------------
1 |1 |2 |Maluku |
1 |1 |2 |Aceh |
1 |1 |2 |Riau |
------------------------------------
my query
SELECT (SELECT COALESCE(COUNT(id),0) FROM vent) as total1,
(SELECT COALESCE(COUNT(id),0) FROM ventWHERE jenis='Vent-I') as total2,
(SELECT COALESCE(COUNT(id),0) FROM ventWHERE status='Terpakai') as total3,
b.provinsi as province
FROM public."admin_provinsi" as b LEFT JOIN
public."rs" as a
on a.provno = b.idprov
GROUP BY b.provinsi, b.idprov
ORDER BY total1 DESC
how to make result of the query like that?
my scheme database
table vent
|id|jenis |id_rs|status |
--------------------------
|1 |vent-i|1 |Terpakai|
|2 |vent-i|2 |Tidak |
table rs
|gid|name |provno|
-----------------
|1 |rs depok | 1 |
|1 |rs depok2| 1 |
table admin_provinsi
|idprov|nama |
---------------
|1 |Maluku|
|2 |Aceh |
|3 |Riau |
I have the following data:
Input:
----------------------------
| Id | Value|
----------------------------
| 1 |A |
| 1 |B |
| 2 |C |
| 2 |D |
| 2 |E |
| 3 |F |
----------------------------
I need to convert the results to the following:
Output (Count is based on Id)
----------------------------
| Id | Value| Count|
----------------------------
| 1 |A | 2 |
| 1 |B | 2 |
| 2 |C | 3 |
| 2 |D | 3 |
| 2 |E | 3 |
| 3 |F | 1 |
----------------------------
I am using SQL server 2008. Is it possible to write a query to do this?
If yes could anyone help me provide a SQL to obtain the above output from the input data I gave.
You are looking for COUNT OVER:
select id, value, count(*) over (partition by id)
from mytable
order by id, value;
I have a table which looks like this :
------------------------
|id | status |value|
------------------------
|1 | Y |10 |
|2 | N |10 |
|3 | Y |10 |
|4 | N |10 |
|5 | N |10 |
------------------------
For every status = 'N', I'd like to add 3 to its value and set its status to 'Y'. So, the outcome table should be:
------------------------
|id | status |value|
------------------------
|1 | Y |10 |
|2 | Y |13 |
|3 | Y |10 |
|4 | Y |13 |
|5 | Y |13 |
------------------------
How can I do this in the best way in SQL Server?
update your_table
set status = 'Y',
value = value + 3
where status = 'N'
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 |